MIFOSX-1786 Allow usage of UGD (Templates) for Hooks
This commit is contained in:
+1035
-1029
File diff suppressed because it is too large
Load Diff
+30
-24
@@ -11,46 +11,52 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class HookApiConstants {
|
public class HookApiConstants {
|
||||||
|
|
||||||
public static final String HOOK_RESOURCE_NAME = "HOOK";
|
public static final String HOOK_RESOURCE_NAME = "HOOK";
|
||||||
|
|
||||||
public static final String nameParamName = "name";
|
public static final String nameParamName = "name";
|
||||||
|
|
||||||
public static final String displayNameParamName = "displayName";
|
public static final String displayNameParamName = "displayName";
|
||||||
|
|
||||||
public static final String isActiveParamName = "isActive";
|
public static final String isActiveParamName = "isActive";
|
||||||
|
|
||||||
public static final String webTemplateName = "Web";
|
public static final String webTemplateName = "Web";
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
public static final String contentTypeName = "Content Type";
|
public static final String contentTypeName = "Content Type";
|
||||||
|
|
||||||
public static final String smsProviderName = "SMS Provider";
|
public static final String smsProviderName = "SMS Provider";
|
||||||
|
|
||||||
public static final String smsProviderAccountIdName = "SMS Provider Account Id";
|
public static final String smsProviderAccountIdName = "SMS Provider Account Id";
|
||||||
|
|
||||||
public static final String smsProviderTokenIdName = "SMS Provider Token";
|
public static final String smsProviderTokenIdName = "SMS Provider Token";
|
||||||
|
|
||||||
public static final String phoneNumberName = "Phone Number";
|
public static final String phoneNumberName = "Phone Number";
|
||||||
|
|
||||||
public static final String apiKeyName = "Api Key";
|
|
||||||
|
|
||||||
public static final String configParamName = "config";
|
public static final String apiKeyName = "Api Key";
|
||||||
|
|
||||||
public static final String eventsParamName = "events";
|
public static final String configParamName = "config";
|
||||||
|
|
||||||
public static final String entityNameParamName = "entityName";
|
public static final String eventsParamName = "events";
|
||||||
|
|
||||||
public static final String actionNameParamName = "actionName";
|
public static final String entityNameParamName = "entityName";
|
||||||
|
|
||||||
public static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
public static final String actionNameParamName = "actionName";
|
||||||
Arrays.asList(nameParamName, displayNameParamName,
|
|
||||||
isActiveParamName, configParamName, eventsParamName));
|
|
||||||
|
|
||||||
public static final Set<String> UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
public static final String templateIdParamName = "templateId";
|
||||||
Arrays.asList(nameParamName, displayNameParamName,
|
|
||||||
isActiveParamName, configParamName, eventsParamName));
|
public static final String templateNameParamName = "templateName";
|
||||||
|
|
||||||
|
public static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
||||||
|
Arrays.asList(nameParamName, displayNameParamName,
|
||||||
|
templateIdParamName, isActiveParamName, configParamName,
|
||||||
|
eventsParamName, templateNameParamName));
|
||||||
|
|
||||||
|
public static final Set<String> UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<>(
|
||||||
|
Arrays.asList(nameParamName, displayNameParamName,
|
||||||
|
templateIdParamName, isActiveParamName, configParamName,
|
||||||
|
eventsParamName, templateNameParamName));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+72
-64
@@ -5,87 +5,95 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.data;
|
package org.mifosplatform.infrastructure.hooks.data;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
|
||||||
|
|
||||||
public class HookData implements Serializable {
|
public class HookData implements Serializable {
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
private final Boolean isActive;
|
private final Boolean isActive;
|
||||||
private final LocalDate createdAt;
|
private final LocalDate createdAt;
|
||||||
private final LocalDate updatedAt;
|
private final LocalDate updatedAt;
|
||||||
|
private final Long templateId;
|
||||||
|
private final String templateName;
|
||||||
|
|
||||||
// associations
|
// associations
|
||||||
private final List<Event> events;
|
private final List<Event> events;
|
||||||
private final List<Field> config;
|
private final List<Field> config;
|
||||||
|
|
||||||
// template data
|
// template data
|
||||||
private final List<HookTemplateData> templates;
|
private final List<HookTemplateData> templates;
|
||||||
private final List<Grouping> groupings;
|
private final List<Grouping> groupings;
|
||||||
|
|
||||||
public static HookData instance(final Long id, final String name,
|
public static HookData instance(final Long id, final String name,
|
||||||
final String displayName, final boolean isActive,
|
final String displayName, final boolean isActive,
|
||||||
final LocalDate createdAt, final LocalDate updatedAt,
|
final LocalDate createdAt, final LocalDate updatedAt,
|
||||||
final List<Event> registeredEvents, final List<Field> config) {
|
final Long templateId, final List<Event> registeredEvents,
|
||||||
return new HookData(id, name, displayName, isActive, createdAt,
|
final List<Field> config, final String templateName) {
|
||||||
updatedAt, registeredEvents, config, null, null);
|
return new HookData(id, name, displayName, isActive, createdAt,
|
||||||
}
|
updatedAt, templateId, registeredEvents, config, templateName,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static HookData template(final List<HookTemplateData> templates,
|
public static HookData template(final List<HookTemplateData> templates,
|
||||||
final List<Grouping> groupings) {
|
final List<Grouping> groupings) {
|
||||||
return new HookData(null, null, null, null, null, null, null, null,
|
return new HookData(null, null, null, null, null, null, null, null,
|
||||||
templates, groupings);
|
null, null, templates, groupings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HookData templateExisting(final HookData hookData,
|
public static HookData templateExisting(final HookData hookData,
|
||||||
final List<HookTemplateData> templates,
|
final List<HookTemplateData> templates,
|
||||||
final List<Grouping> groupings) {
|
final List<Grouping> groupings) {
|
||||||
return new HookData(hookData.id, hookData.name, hookData.displayName,
|
return new HookData(hookData.id, hookData.name, hookData.displayName,
|
||||||
hookData.isActive, hookData.createdAt, hookData.updatedAt,
|
hookData.isActive, hookData.createdAt, hookData.updatedAt,
|
||||||
hookData.events, hookData.config, templates, groupings);
|
hookData.templateId, hookData.events, hookData.config,
|
||||||
}
|
hookData.templateName, templates, groupings);
|
||||||
|
}
|
||||||
|
|
||||||
private HookData(final Long id, final String name,
|
private HookData(final Long id, final String name,
|
||||||
final String displayName, final Boolean isActive,
|
final String displayName, final Boolean isActive,
|
||||||
final LocalDate createdAt, final LocalDate updatedAt,
|
final LocalDate createdAt, final LocalDate updatedAt,
|
||||||
final List<Event> events, final List<Field> config,
|
final Long templateId, final List<Event> events,
|
||||||
final List<HookTemplateData> templates,
|
final List<Field> config, final String templateName,
|
||||||
final List<Grouping> groupings) {
|
final List<HookTemplateData> templates,
|
||||||
this.id = id;
|
final List<Grouping> groupings) {
|
||||||
this.name = name;
|
this.id = id;
|
||||||
this.displayName = displayName;
|
this.name = name;
|
||||||
this.isActive = isActive;
|
this.displayName = displayName;
|
||||||
this.createdAt = createdAt;
|
this.isActive = isActive;
|
||||||
this.updatedAt = updatedAt;
|
this.createdAt = createdAt;
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
this.templateId = templateId;
|
||||||
|
this.templateName = templateName;
|
||||||
|
|
||||||
// associations
|
// associations
|
||||||
this.events = events;
|
this.events = events;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
// template
|
// template
|
||||||
this.templates = templates;
|
this.templates = templates;
|
||||||
this.groupings = groupings;
|
this.groupings = groupings;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getHookId() {
|
public Long getHookId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HookTemplateData> getTemplates() {
|
public List<HookTemplateData> getTemplates() {
|
||||||
return this.templates;
|
return this.templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Grouping> getGroupings() {
|
public List<Grouping> getGroupings() {
|
||||||
return this.groupings;
|
return this.groupings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTemplateName() {
|
public String getTemplateName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+154
-139
@@ -5,183 +5,198 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.domain;
|
package org.mifosplatform.infrastructure.hooks.domain;
|
||||||
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.configParamName;
|
import com.google.gson.JsonArray;
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.displayNameParamName;
|
import com.google.gson.JsonElement;
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.eventsParamName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.isActiveParamName;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.hibernate.annotations.LazyCollection;
|
import org.hibernate.annotations.LazyCollection;
|
||||||
import org.hibernate.annotations.LazyCollectionOption;
|
import org.hibernate.annotations.LazyCollectionOption;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||||
|
import org.mifosplatform.template.domain.Template;
|
||||||
import org.mifosplatform.useradministration.domain.AppUser;
|
import org.mifosplatform.useradministration.domain.AppUser;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import javax.persistence.*;
|
||||||
import com.google.gson.JsonElement;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.*;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_hook")
|
@Table(name = "m_hook")
|
||||||
public class Hook extends AbstractAuditableCustom<AppUser, Long> {
|
public class Hook extends AbstractAuditableCustom<AppUser, Long> {
|
||||||
|
|
||||||
@Column(name = "name", nullable = false, length = 100)
|
@Column(name = "name", nullable = false, length = 100)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Column(name = "is_active", nullable = false)
|
@Column(name = "is_active", nullable = false)
|
||||||
private Boolean isActive;
|
private Boolean isActive;
|
||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true)
|
||||||
private Set<HookResource> events = new HashSet<>();
|
private Set<HookResource> events = new HashSet<>();
|
||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true)
|
||||||
private Set<HookConfiguration> config = new HashSet<>();
|
private Set<HookConfiguration> config = new HashSet<>();
|
||||||
|
|
||||||
@ManyToOne(optional = true)
|
@ManyToOne(optional = true)
|
||||||
@JoinColumn(name = "template_id", referencedColumnName = "id", nullable = false)
|
@JoinColumn(name = "template_id", referencedColumnName = "id", nullable = false)
|
||||||
private HookTemplate template;
|
private HookTemplate template;
|
||||||
|
|
||||||
protected Hook() {
|
@ManyToOne(optional = true)
|
||||||
//
|
@JoinColumn(name = "ugd_template_id", referencedColumnName = "id", nullable = false)
|
||||||
}
|
private Template ugdTemplate;
|
||||||
|
|
||||||
public static Hook fromJson(final JsonCommand command,
|
protected Hook() {
|
||||||
final HookTemplate template, final Set<HookConfiguration> config,
|
//
|
||||||
final Set<HookResource> events) {
|
}
|
||||||
final String displayName = command
|
|
||||||
.stringValueOfParameterNamed(displayNameParamName);
|
public static Hook fromJson(final JsonCommand command,
|
||||||
Boolean isActive = command
|
final HookTemplate template, final Set<HookConfiguration> config,
|
||||||
.booleanObjectValueOfParameterNamed(isActiveParamName);
|
final Set<HookResource> events, final Template ugdTemplate) {
|
||||||
if(isActive == null)
|
final String displayName = command
|
||||||
|
.stringValueOfParameterNamed(displayNameParamName);
|
||||||
|
Boolean isActive = command
|
||||||
|
.booleanObjectValueOfParameterNamed(isActiveParamName);
|
||||||
|
if (isActive == null)
|
||||||
isActive = false;
|
isActive = false;
|
||||||
return new Hook(template, displayName, isActive, config, events);
|
return new Hook(template, displayName, isActive, config, events,
|
||||||
}
|
ugdTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
private Hook(final HookTemplate template, final String displayName,
|
private Hook(final HookTemplate template, final String displayName,
|
||||||
final Boolean isActive, final Set<HookConfiguration> config,
|
final Boolean isActive, final Set<HookConfiguration> config,
|
||||||
final Set<HookResource> events) {
|
final Set<HookResource> events, final Template ugdTemplate) {
|
||||||
|
|
||||||
this.template = template;
|
this.template = template;
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(displayName)) {
|
if (StringUtils.isNotBlank(displayName)) {
|
||||||
this.name = displayName.trim();
|
this.name = displayName.trim();
|
||||||
} else {
|
} else {
|
||||||
this.name = template.getName();
|
this.name = template.getName();
|
||||||
}
|
}
|
||||||
this.isActive = isActive;
|
this.isActive = isActive;
|
||||||
if (!CollectionUtils.isEmpty(config)) {
|
if (!CollectionUtils.isEmpty(config)) {
|
||||||
this.config = associateConfigWithThisHook(config);
|
this.config = associateConfigWithThisHook(config);
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(events)) {
|
if (!CollectionUtils.isEmpty(events)) {
|
||||||
this.events = associateEventsWithThisHook(events);
|
this.events = associateEventsWithThisHook(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
this.ugdTemplate = ugdTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
private Set<HookConfiguration> associateConfigWithThisHook(
|
private Set<HookConfiguration> associateConfigWithThisHook(
|
||||||
final Set<HookConfiguration> config) {
|
final Set<HookConfiguration> config) {
|
||||||
for (final HookConfiguration hookConfiguration : config) {
|
for (final HookConfiguration hookConfiguration : config) {
|
||||||
hookConfiguration.update(this);
|
hookConfiguration.update(this);
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<HookResource> associateEventsWithThisHook(
|
private Set<HookResource> associateEventsWithThisHook(
|
||||||
final Set<HookResource> events) {
|
final Set<HookResource> events) {
|
||||||
for (final HookResource hookResource : events) {
|
for (final HookResource hookResource : events) {
|
||||||
hookResource.update(this);
|
hookResource.update(this);
|
||||||
}
|
}
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HookTemplate getHookTemplate() {
|
public HookTemplate getHookTemplate() {
|
||||||
return this.template;
|
return this.template;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<HookConfiguration> getHookConfig() {
|
public Template getUgdTemplate() {
|
||||||
return this.config;
|
return this.ugdTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command) {
|
public Long getUgdTemplateId() {
|
||||||
|
return this.ugdTemplate.getId();
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(4);
|
public Set<HookConfiguration> getHookConfig() {
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
if (command.isChangeInStringParameterNamed(displayNameParamName,
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
this.name)) {
|
|
||||||
final String newValue = command
|
|
||||||
.stringValueOfParameterNamed(displayNameParamName);
|
|
||||||
actualChanges.put(displayNameParamName, newValue);
|
|
||||||
this.name = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.isChangeInBooleanParameterNamed(isActiveParamName,
|
final Map<String, Object> actualChanges = new LinkedHashMap<>(5);
|
||||||
this.isActive)) {
|
|
||||||
final Boolean newValue = command
|
|
||||||
.booleanObjectValueOfParameterNamed(isActiveParamName);
|
|
||||||
actualChanges.put(isActiveParamName, newValue);
|
|
||||||
this.isActive = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// events
|
if (command.isChangeInStringParameterNamed(displayNameParamName,
|
||||||
if (command.hasParameter(eventsParamName)) {
|
this.name)) {
|
||||||
final JsonArray jsonArray = command
|
final String newValue = command
|
||||||
.arrayOfParameterNamed(eventsParamName);
|
.stringValueOfParameterNamed(displayNameParamName);
|
||||||
if (jsonArray != null) {
|
actualChanges.put(displayNameParamName, newValue);
|
||||||
actualChanges.put(eventsParamName, jsonArray);
|
this.name = newValue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// config
|
if (command.isChangeInBooleanParameterNamed(isActiveParamName,
|
||||||
if (command.hasParameter(configParamName)) {
|
this.isActive)) {
|
||||||
final JsonElement element = command.parsedJson().getAsJsonObject()
|
final Boolean newValue = command
|
||||||
.get(configParamName);
|
.booleanObjectValueOfParameterNamed(isActiveParamName);
|
||||||
if (element != null) {
|
actualChanges.put(isActiveParamName, newValue);
|
||||||
actualChanges.put(configParamName, element);
|
this.isActive = newValue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return actualChanges;
|
if (command.isChangeInLongParameterNamed(templateIdParamName,
|
||||||
}
|
getUgdTemplateId())) {
|
||||||
|
final Long newValue = command
|
||||||
|
.longValueOfParameterNamed(templateIdParamName);
|
||||||
|
actualChanges.put(templateIdParamName, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean updateEvents(final Set<HookResource> newHookEvents) {
|
// events
|
||||||
if (newHookEvents == null) {
|
if (command.hasParameter(eventsParamName)) {
|
||||||
return false;
|
final JsonArray jsonArray = command
|
||||||
}
|
.arrayOfParameterNamed(eventsParamName);
|
||||||
|
if (jsonArray != null) {
|
||||||
|
actualChanges.put(eventsParamName, jsonArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.events == null) {
|
// config
|
||||||
this.events = new HashSet<>();
|
if (command.hasParameter(configParamName)) {
|
||||||
}
|
final JsonElement element = command.parsedJson().getAsJsonObject()
|
||||||
this.events.clear();
|
.get(configParamName);
|
||||||
this.events.addAll(associateEventsWithThisHook(newHookEvents));
|
if (element != null) {
|
||||||
return true;
|
actualChanges.put(configParamName, element);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean updateConfig(final Set<HookConfiguration> newHookConfig) {
|
return actualChanges;
|
||||||
if (newHookConfig == null) {
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.config == null) {
|
public boolean updateEvents(final Set<HookResource> newHookEvents) {
|
||||||
this.config = new HashSet<>();
|
if (newHookEvents == null) {
|
||||||
}
|
return false;
|
||||||
this.config.clear();
|
}
|
||||||
this.config.addAll(associateConfigWithThisHook(newHookConfig));
|
|
||||||
return true;
|
if (this.events == null) {
|
||||||
}
|
this.events = new HashSet<>();
|
||||||
|
}
|
||||||
|
this.events.clear();
|
||||||
|
this.events.addAll(associateEventsWithThisHook(newHookEvents));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateConfig(final Set<HookConfiguration> newHookConfig) {
|
||||||
|
if (newHookConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.config == null) {
|
||||||
|
this.config = new HashSet<>();
|
||||||
|
}
|
||||||
|
this.config.clear();
|
||||||
|
this.config.addAll(associateConfigWithThisHook(newHookConfig));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUgdTemplate(final Template ugdTemplate) {
|
||||||
|
this.ugdTemplate = ugdTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-36
@@ -5,8 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.listener;
|
package org.mifosplatform.infrastructure.hooks.listener;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
import org.mifosplatform.infrastructure.core.domain.MifosPlatformTenant;
|
||||||
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
||||||
@@ -20,48 +18,50 @@ import org.mifosplatform.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 java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MifosHookListener implements HookListener {
|
public class MifosHookListener implements HookListener {
|
||||||
|
|
||||||
private final HookProcessorProvider hookProcessorProvider;
|
private final HookProcessorProvider hookProcessorProvider;
|
||||||
private final HookReadPlatformService hookReadPlatformService;
|
private final HookReadPlatformService hookReadPlatformService;
|
||||||
private final TenantDetailsService tenantDetailsService;
|
private final TenantDetailsService tenantDetailsService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MifosHookListener(final HookProcessorProvider hookProcessorProvider,
|
public MifosHookListener(final HookProcessorProvider hookProcessorProvider,
|
||||||
final HookReadPlatformService hookReadPlatformService,
|
final HookReadPlatformService hookReadPlatformService,
|
||||||
final TenantDetailsService tenantDetailsService) {
|
final TenantDetailsService tenantDetailsService) {
|
||||||
this.hookReadPlatformService = hookReadPlatformService;
|
this.hookReadPlatformService = hookReadPlatformService;
|
||||||
this.hookProcessorProvider = hookProcessorProvider;
|
this.hookProcessorProvider = hookProcessorProvider;
|
||||||
this.tenantDetailsService = tenantDetailsService;
|
this.tenantDetailsService = tenantDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 MifosPlatformTenant tenant = this.tenantDetailsService
|
final MifosPlatformTenant tenant = this.tenantDetailsService
|
||||||
.loadTenantById(tenantIdentifier);
|
.loadTenantById(tenantIdentifier);
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
|
|
||||||
final AppUser appUser = event.getAppUser();
|
final AppUser appUser = event.getAppUser();
|
||||||
final String authToken = event.getAuthToken();
|
final String authToken = event.getAuthToken();
|
||||||
|
|
||||||
final HookEventSource hookEventSource = event.getSource();
|
final HookEventSource hookEventSource = event.getSource();
|
||||||
final String entityName = hookEventSource.getEntityName();
|
final String entityName = hookEventSource.getEntityName();
|
||||||
final String actionName = hookEventSource.getActionName();
|
final String actionName = hookEventSource.getActionName();
|
||||||
final String payload = event.getPayload();
|
final String payload = event.getPayload();
|
||||||
|
|
||||||
final List<Hook> hooks = this.hookReadPlatformService
|
|
||||||
.retrieveHooksByEvent(hookEventSource.getEntityName(),
|
|
||||||
hookEventSource.getActionName());
|
|
||||||
|
|
||||||
for (final Hook hook : hooks) {
|
final List<Hook> hooks = this.hookReadPlatformService
|
||||||
final HookProcessor processor = this.hookProcessorProvider
|
.retrieveHooksByEvent(hookEventSource.getEntityName(),
|
||||||
.getProcessor(hook);
|
hookEventSource.getActionName());
|
||||||
processor.process(hook, appUser, payload, entityName, actionName,
|
|
||||||
tenantIdentifier, authToken);
|
for (final Hook hook : hooks) {
|
||||||
}
|
final HookProcessor processor = this.hookProcessorProvider
|
||||||
}
|
.getProcessor(hook);
|
||||||
|
processor.process(hook, appUser, payload, entityName, actionName,
|
||||||
|
tenantIdentifier, authToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+103
-51
@@ -5,79 +5,131 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.processor;
|
package org.mifosplatform.infrastructure.hooks.processor;
|
||||||
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.apiKeyName;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookConfiguration;
|
import org.mifosplatform.infrastructure.hooks.domain.HookConfiguration;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookConfigurationRepository;
|
import org.mifosplatform.infrastructure.hooks.domain.HookConfigurationRepository;
|
||||||
import org.mifosplatform.infrastructure.hooks.processor.data.SmsProviderData;
|
import org.mifosplatform.infrastructure.hooks.processor.data.SmsProviderData;
|
||||||
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
|
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||||
|
import org.mifosplatform.template.service.TemplateMergeService;
|
||||||
import org.mifosplatform.useradministration.domain.AppUser;
|
import org.mifosplatform.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 retrofit.Callback;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import java.io.IOException;
|
||||||
import com.google.gson.JsonParser;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.apiKeyName;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TwilioHookProcessor implements HookProcessor {
|
public class TwilioHookProcessor implements HookProcessor {
|
||||||
|
|
||||||
private final HookConfigurationRepository hookConfigurationRepository;
|
private final HookConfigurationRepository hookConfigurationRepository;
|
||||||
|
private final TemplateMergeService templateMergeService;
|
||||||
|
private final ClientRepository clientRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public TwilioHookProcessor(
|
public TwilioHookProcessor(
|
||||||
final HookConfigurationRepository hookConfigurationRepository) {
|
final HookConfigurationRepository hookConfigurationRepository,
|
||||||
this.hookConfigurationRepository = hookConfigurationRepository;
|
final TemplateMergeService templateMergeService,
|
||||||
}
|
final ClientRepository clientRepository) {
|
||||||
|
this.hookConfigurationRepository = hookConfigurationRepository;
|
||||||
|
this.templateMergeService = templateMergeService;
|
||||||
|
this.clientRepository = clientRepository;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook,
|
public void process(final Hook hook,
|
||||||
@SuppressWarnings("unused") final AppUser appUser,
|
@SuppressWarnings("unused") final AppUser appUser,
|
||||||
final String payload, final String entityName,
|
final String payload, final String entityName,
|
||||||
final String actionName, final String tenantIdentifier,
|
final String actionName, final String tenantIdentifier,
|
||||||
final String authToken) {
|
final String authToken) {
|
||||||
|
|
||||||
final SmsProviderData smsProviderData = new SmsProviderData(
|
final SmsProviderData smsProviderData = new SmsProviderData(
|
||||||
hook.getHookConfig());
|
hook.getHookConfig());
|
||||||
|
|
||||||
sendRequest(smsProviderData, payload, entityName, actionName,
|
sendRequest(smsProviderData, payload, entityName, actionName,
|
||||||
tenantIdentifier, authToken, hook);
|
tenantIdentifier, authToken, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void sendRequest(final SmsProviderData smsProviderData,
|
private void sendRequest(final SmsProviderData smsProviderData,
|
||||||
final String payload, final String entityName,
|
final String payload, String entityName, String actionName,
|
||||||
final String actionName, final String tenantIdentifier,
|
final String tenantIdentifier, final String authToken,
|
||||||
final String authToken, final Hook hook) {
|
final Hook hook) {
|
||||||
|
|
||||||
final WebHookService service = ProcessorHelper
|
final WebHookService service = ProcessorHelper
|
||||||
.createWebHookService(smsProviderData.getUrl());
|
.createWebHookService(smsProviderData.getUrl());
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
final Callback callback = ProcessorHelper
|
final Callback callback = ProcessorHelper
|
||||||
.createCallback(smsProviderData.getUrl());
|
.createCallback(smsProviderData.getUrl());
|
||||||
|
|
||||||
String apiKey = this.hookConfigurationRepository
|
String apiKey = this.hookConfigurationRepository
|
||||||
.findOneByHookIdAndFieldName(hook.getId(), apiKeyName);
|
.findOneByHookIdAndFieldName(hook.getId(), apiKeyName);
|
||||||
if (apiKey == null) {
|
if (apiKey == null) {
|
||||||
smsProviderData.setUrl(null);
|
smsProviderData.setUrl(null);
|
||||||
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);
|
||||||
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(
|
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(
|
||||||
hook, "string", apiKeyName, apiKey);
|
hook, "string", apiKeyName, apiKey);
|
||||||
this.hookConfigurationRepository.save(apiKeyEntry);
|
this.hookConfigurationRepository.save(apiKeyEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiKey != null && !apiKey.equals("")) {
|
if (apiKey != null && !apiKey.equals("")) {
|
||||||
final JsonObject json = new JsonParser().parse(payload)
|
JsonObject json = null;
|
||||||
.getAsJsonObject();
|
if (hook.getUgdTemplate() != null) {
|
||||||
service.sendSmsBridgeRequest(entityName, actionName,
|
entityName = "sms";
|
||||||
tenantIdentifier, apiKey, json, callback);
|
actionName = "send";
|
||||||
}
|
json = processUgdTemplate(payload, hook, authToken);
|
||||||
|
if (json == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json = new JsonParser().parse(payload).getAsJsonObject();
|
||||||
|
}
|
||||||
|
service.sendSmsBridgeRequest(entityName, actionName,
|
||||||
|
tenantIdentifier, apiKey, json, callback);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JsonObject processUgdTemplate(final String payload,
|
||||||
|
final Hook hook, final String authToken) {
|
||||||
|
JsonObject json = null;
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final HashMap<String, Object> map = new ObjectMapper().readValue(
|
||||||
|
payload, HashMap.class);
|
||||||
|
map.put("BASE_URI", System.getProperty("baseUrl"));
|
||||||
|
if (map.containsKey("clientId")) {
|
||||||
|
final Long clientId = new Long(Integer.toString((int) map
|
||||||
|
.get("clientId")));
|
||||||
|
final Client client = this.clientRepository.findOne(clientId);
|
||||||
|
final String mobileNo = client.mobileNo();
|
||||||
|
if (mobileNo != null && !mobileNo.isEmpty()) {
|
||||||
|
this.templateMergeService.setAuthToken(authToken);
|
||||||
|
final String compiledMessage = this.templateMergeService
|
||||||
|
.compile(hook.getUgdTemplate(), map)
|
||||||
|
.replace("<p>", "").replace("</p>", "");
|
||||||
|
final Map<String, String> jsonMap = new HashMap<>();
|
||||||
|
jsonMap.put("mobileNo", mobileNo);
|
||||||
|
jsonMap.put("message", compiledMessage);
|
||||||
|
final String jsonString = new Gson().toJson(jsonMap);
|
||||||
|
json = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-67
@@ -5,98 +5,112 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.serialization;
|
package org.mifosplatform.infrastructure.hooks.serialization;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import com.google.gson.JsonElement;
|
||||||
import java.util.ArrayList;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.mifosplatform.infrastructure.hooks.api.HookApiConstants;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import java.lang.reflect.Type;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import java.util.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class HookCommandFromApiJsonDeserializer {
|
public class HookCommandFromApiJsonDeserializer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parameters supported for this command.
|
* The parameters supported for this command.
|
||||||
*/
|
*/
|
||||||
private final Set<String> supportedParameters = new HashSet<>(
|
private final Set<String> supportedParameters = new HashSet<>(
|
||||||
Arrays.asList("name", "displayName", "isActive", "events", "config"));
|
Arrays.asList("name", "displayName", "isActive", "events",
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
"config", "templateId"));
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HookCommandFromApiJsonDeserializer(
|
public HookCommandFromApiJsonDeserializer(
|
||||||
final FromJsonHelper fromApiJsonHelper) {
|
final FromJsonHelper fromApiJsonHelper) {
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateForCreate(final String json) {
|
public void validateForCreate(final String json) {
|
||||||
if (StringUtils.isBlank(json)) {
|
if (StringUtils.isBlank(json)) {
|
||||||
throw new InvalidJsonException();
|
throw new InvalidJsonException();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
||||||
}.getType();
|
}.getType();
|
||||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
||||||
this.supportedParameters);
|
this.supportedParameters);
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
||||||
dataValidationErrors).resource("hook");
|
dataValidationErrors).resource("hook");
|
||||||
|
|
||||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
|
|
||||||
final String name = this.fromApiJsonHelper.extractStringNamed("name",
|
final String name = this.fromApiJsonHelper.extractStringNamed("name",
|
||||||
element);
|
element);
|
||||||
baseDataValidator.reset().parameter("name").value(name).notBlank()
|
baseDataValidator.reset().parameter("name").value(name).notBlank()
|
||||||
.notExceedingLengthOf(100);
|
.notExceedingLengthOf(100);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
if (this.fromApiJsonHelper.parameterExists(
|
||||||
}
|
HookApiConstants.templateIdParamName, element)) {
|
||||||
|
final Long templateId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
|
HookApiConstants.templateIdParamName, element);
|
||||||
|
baseDataValidator.reset()
|
||||||
|
.parameter(HookApiConstants.templateIdParamName)
|
||||||
|
.value(templateId).notNull().integerGreaterThanZero();
|
||||||
|
}
|
||||||
|
|
||||||
public void validateForUpdate(final String json) {
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
if (StringUtils.isBlank(json)) {
|
}
|
||||||
throw new InvalidJsonException();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
public void validateForUpdate(final String json) {
|
||||||
}.getType();
|
if (StringUtils.isBlank(json)) {
|
||||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
throw new InvalidJsonException();
|
||||||
this.supportedParameters);
|
}
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
}.getType();
|
||||||
dataValidationErrors).resource("hook");
|
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
||||||
|
this.supportedParameters);
|
||||||
|
|
||||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
if (this.fromApiJsonHelper.parameterExists("name", element)) {
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
||||||
final String name = this.fromApiJsonHelper.extractStringNamed(
|
dataValidationErrors).resource("hook");
|
||||||
"name", element);
|
|
||||||
baseDataValidator.reset().parameter("name").value(name).notBlank()
|
|
||||||
.notExceedingLengthOf(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
}
|
if (this.fromApiJsonHelper.parameterExists("name", element)) {
|
||||||
|
final String name = this.fromApiJsonHelper.extractStringNamed(
|
||||||
|
"name", element);
|
||||||
|
baseDataValidator.reset().parameter("name").value(name).notBlank()
|
||||||
|
.notExceedingLengthOf(100);
|
||||||
|
}
|
||||||
|
|
||||||
private void throwExceptionIfValidationWarningsExist(
|
if (this.fromApiJsonHelper.parameterExists(
|
||||||
final List<ApiParameterError> dataValidationErrors) {
|
HookApiConstants.templateIdParamName, element)) {
|
||||||
if (!dataValidationErrors.isEmpty()) {
|
final Long templateId = this.fromApiJsonHelper.extractLongNamed(
|
||||||
throw new PlatformApiDataValidationException(
|
HookApiConstants.templateIdParamName, element);
|
||||||
"validation.msg.validation.errors.exist",
|
baseDataValidator.reset()
|
||||||
"Validation errors exist.", dataValidationErrors);
|
.parameter(HookApiConstants.templateIdParamName)
|
||||||
}
|
.value(templateId).notNull().integerGreaterThanZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void throwExceptionIfValidationWarningsExist(
|
||||||
|
final List<ApiParameterError> dataValidationErrors) {
|
||||||
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
|
throw new PlatformApiDataValidationException(
|
||||||
|
"validation.msg.validation.errors.exist",
|
||||||
|
"Validation errors exist.", dataValidationErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+183
-182
@@ -5,20 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.service;
|
package org.mifosplatform.infrastructure.hooks.service;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||||
import org.mifosplatform.infrastructure.hooks.data.Event;
|
import org.mifosplatform.infrastructure.hooks.data.*;
|
||||||
import org.mifosplatform.infrastructure.hooks.data.EventResultSetExtractor;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.data.Field;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.data.Grouping;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.data.HookData;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.data.HookTemplateData;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookRepository;
|
import org.mifosplatform.infrastructure.hooks.domain.HookRepository;
|
||||||
import org.mifosplatform.infrastructure.hooks.exception.HookNotFoundException;
|
import org.mifosplatform.infrastructure.hooks.exception.HookNotFoundException;
|
||||||
@@ -30,227 +20,238 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class HookReadPlatformServiceImpl implements HookReadPlatformService {
|
public class HookReadPlatformServiceImpl implements HookReadPlatformService {
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final HookRepository hookRepository;
|
private final HookRepository hookRepository;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HookReadPlatformServiceImpl(final PlatformSecurityContext context,
|
public HookReadPlatformServiceImpl(final PlatformSecurityContext context,
|
||||||
final HookRepository hookRepository,
|
final HookRepository hookRepository,
|
||||||
final RoutingDataSource dataSource) {
|
final RoutingDataSource dataSource) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.hookRepository = hookRepository;
|
this.hookRepository = hookRepository;
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<HookData> retrieveAllHooks() {
|
public Collection<HookData> retrieveAllHooks() {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
final HookMapper rm = new HookMapper(this.jdbcTemplate);
|
final HookMapper rm = new HookMapper(this.jdbcTemplate);
|
||||||
final String sql = "select " + rm.schema() + " order by h.name";
|
final String sql = "select " + rm.schema() + " order by h.name";
|
||||||
|
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
return this.jdbcTemplate.query(sql, rm, new Object[]{});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HookData retrieveHook(final Long hookId) {
|
public HookData retrieveHook(final Long hookId) {
|
||||||
try {
|
try {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
final HookMapper rm = new HookMapper(this.jdbcTemplate);
|
final HookMapper rm = new HookMapper(this.jdbcTemplate);
|
||||||
final String sql = "select " + rm.schema() + " where h.id = ?";
|
final String sql = "select " + rm.schema() + " where h.id = ?";
|
||||||
|
|
||||||
return this.jdbcTemplate.queryForObject(sql, rm,
|
return this.jdbcTemplate.queryForObject(sql, rm,
|
||||||
new Object[] { hookId });
|
new Object[]{hookId});
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
throw new HookNotFoundException(hookId);
|
throw new HookNotFoundException(hookId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "hooks", key = "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('HK')")
|
@Cacheable(value = "hooks", key = "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('HK')")
|
||||||
public List<Hook> retrieveHooksByEvent(final String actionName,
|
public List<Hook> retrieveHooksByEvent(final String actionName,
|
||||||
final String entityName) {
|
final String entityName) {
|
||||||
|
|
||||||
return this.hookRepository.findAllHooksListeningToEvent(actionName,
|
return this.hookRepository.findAllHooksListeningToEvent(actionName,
|
||||||
entityName);
|
entityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HookData retrieveNewHookDetails(final String templateName) {
|
public HookData retrieveNewHookDetails(final String templateName) {
|
||||||
|
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
final TemplateMapper rm = new TemplateMapper(this.jdbcTemplate);
|
final TemplateMapper rm = new TemplateMapper(this.jdbcTemplate);
|
||||||
final String sql;
|
final String sql;
|
||||||
List<HookTemplateData> templateData;
|
List<HookTemplateData> templateData;
|
||||||
|
|
||||||
if (templateName == null) {
|
if (templateName == null) {
|
||||||
sql = "select " + rm.schema() + " order by s.name";
|
sql = "select " + rm.schema() + " order by s.name";
|
||||||
templateData = this.jdbcTemplate.query(sql, rm, new Object[] {});
|
templateData = this.jdbcTemplate.query(sql, rm, new Object[]{});
|
||||||
} else {
|
} else {
|
||||||
sql = "select " + rm.schema() + " where s.name = ? order by s.name";
|
sql = "select " + rm.schema() + " where s.name = ? order by s.name";
|
||||||
templateData = this.jdbcTemplate.query(sql, rm,
|
templateData = this.jdbcTemplate.query(sql, rm,
|
||||||
new Object[] { templateName });
|
new Object[]{templateName});
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Grouping> events = getTemplateForEvents();
|
final List<Grouping> events = getTemplateForEvents();
|
||||||
|
|
||||||
return HookData.template(templateData, events);
|
return HookData.template(templateData, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Grouping> getTemplateForEvents() {
|
private List<Grouping> getTemplateForEvents() {
|
||||||
final String sql = "select p.grouping, p.entity_name, p.action_name from m_permission p "
|
final String sql = "select p.grouping, p.entity_name, p.action_name from m_permission p "
|
||||||
+ " where p.action_name NOT LIKE '%CHECKER%' AND p.action_name NOT LIKE '%READ%' "
|
+ " where p.action_name NOT LIKE '%CHECKER%' AND p.action_name NOT LIKE '%READ%' "
|
||||||
+ " order by p.grouping, p.entity_name ";
|
+ " order by p.grouping, p.entity_name ";
|
||||||
final EventResultSetExtractor extractor = new EventResultSetExtractor();
|
final EventResultSetExtractor extractor = new EventResultSetExtractor();
|
||||||
return this.jdbcTemplate.query(sql, extractor);
|
return this.jdbcTemplate.query(sql, extractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class HookMapper implements RowMapper<HookData> {
|
private static final class HookMapper implements RowMapper<HookData> {
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
public HookMapper(final JdbcTemplate jdbcTemplate) {
|
public HookMapper(final JdbcTemplate jdbcTemplate) {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " h.id, s.name as name, h.name as display_name, h.is_active, h.created_date, h.lastmodified_date "
|
return " h.id, s.name as name, h.name as display_name, h.is_active, h.created_date,"
|
||||||
+ " from m_hook h inner join m_hook_templates s on h.template_id = s.id ";
|
+ " h.lastmodified_date, h.ugd_template_id, tp.name as ugd_template_name, "
|
||||||
}
|
+ "h.ugd_template_id from m_hook h inner join m_hook_templates s on h.template_id = s.id"
|
||||||
|
+ " inner join m_template tp on h.ugd_template_id = tp.id";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HookData mapRow(final ResultSet rs,
|
public HookData mapRow(final ResultSet rs,
|
||||||
@SuppressWarnings("unused") final int rowNum)
|
@SuppressWarnings("unused") final int rowNum)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
|
|
||||||
final Long id = rs.getLong("id");
|
final Long id = rs.getLong("id");
|
||||||
final String name = rs.getString("name");
|
final String name = rs.getString("name");
|
||||||
final String displayname = rs.getString("display_name");
|
final String displayname = rs.getString("display_name");
|
||||||
final boolean isActive = rs.getBoolean("is_active");
|
final boolean isActive = rs.getBoolean("is_active");
|
||||||
final LocalDate createdAt = JdbcSupport.getLocalDate(rs,
|
final LocalDate createdAt = JdbcSupport.getLocalDate(rs,
|
||||||
"created_date");
|
"created_date");
|
||||||
final LocalDate updatedAt = JdbcSupport.getLocalDate(rs,
|
final LocalDate updatedAt = JdbcSupport.getLocalDate(rs,
|
||||||
"lastmodified_date");
|
"lastmodified_date");
|
||||||
final List<Event> registeredEvents = retrieveEvents(id);
|
final Long templateId = rs.getLong("ugd_template_id");
|
||||||
final List<Field> config = retrieveConfig(id);
|
final String templateName = rs.getString("ugd_template_name");
|
||||||
|
final List<Event> registeredEvents = retrieveEvents(id);
|
||||||
|
final List<Field> config = retrieveConfig(id);
|
||||||
|
|
||||||
return HookData.instance(id, name, displayname, isActive,
|
return HookData.instance(id, name, displayname, isActive,
|
||||||
createdAt, updatedAt, registeredEvents, config);
|
createdAt, updatedAt, templateId, registeredEvents, config,
|
||||||
}
|
templateName);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Event> retrieveEvents(final Long hookId) {
|
private List<Event> retrieveEvents(final Long hookId) {
|
||||||
|
|
||||||
final HookEventMapper rm = new HookEventMapper();
|
final HookEventMapper rm = new HookEventMapper();
|
||||||
final String sql = "select " + rm.schema() + " where h.id= ?";
|
final String sql = "select " + rm.schema() + " where h.id= ?";
|
||||||
|
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[] { hookId });
|
return this.jdbcTemplate.query(sql, rm, new Object[]{hookId});
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Field> retrieveConfig(final Long hookId) {
|
private List<Field> retrieveConfig(final Long hookId) {
|
||||||
|
|
||||||
final HookConfigMapper rm = new HookConfigMapper();
|
final HookConfigMapper rm = new HookConfigMapper();
|
||||||
final String sql = "select " + rm.schema()
|
final String sql = "select " + rm.schema()
|
||||||
+ " where h.id= ? order by hc.field_name";
|
+ " where h.id= ? order by hc.field_name";
|
||||||
|
|
||||||
final List<Field> fields = this.jdbcTemplate.query(sql, rm,
|
final List<Field> fields = this.jdbcTemplate.query(sql, rm,
|
||||||
new Object[] { hookId });
|
new Object[]{hookId});
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class HookEventMapper implements RowMapper<Event> {
|
private static final class HookEventMapper implements RowMapper<Event> {
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " re.action_name, re.entity_name from m_hook h inner join m_hook_registered_events re on h.id = re.hook_id ";
|
return " re.action_name, re.entity_name from m_hook h inner join m_hook_registered_events re on h.id = re.hook_id ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Event mapRow(final ResultSet rs,
|
public Event mapRow(final ResultSet rs,
|
||||||
@SuppressWarnings("unused") final int rowNum)
|
@SuppressWarnings("unused") final int rowNum)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
final String actionName = rs.getString("action_name");
|
final String actionName = rs.getString("action_name");
|
||||||
final String entityName = rs.getString("entity_name");
|
final String entityName = rs.getString("entity_name");
|
||||||
return Event.instance(actionName, entityName);
|
return Event.instance(actionName, entityName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class HookConfigMapper implements RowMapper<Field> {
|
private static final class HookConfigMapper implements RowMapper<Field> {
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " hc.field_name, hc.field_value from m_hook h inner join m_hook_configuration hc on h.id = hc.hook_id ";
|
return " hc.field_name, hc.field_value from m_hook h inner join m_hook_configuration hc on h.id = hc.hook_id ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Field mapRow(final ResultSet rs,
|
public Field mapRow(final ResultSet rs,
|
||||||
@SuppressWarnings("unused") final int rowNum)
|
@SuppressWarnings("unused") final int rowNum)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
final String fieldName = rs.getString("field_name");
|
final String fieldName = rs.getString("field_name");
|
||||||
final String fieldValue = rs.getString("field_value");
|
final String fieldValue = rs.getString("field_value");
|
||||||
return Field.fromConfig(fieldName, fieldValue);
|
return Field.fromConfig(fieldName, fieldValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class TemplateMapper implements
|
private static final class TemplateMapper
|
||||||
RowMapper<HookTemplateData> {
|
implements
|
||||||
|
RowMapper<HookTemplateData> {
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
public TemplateMapper(final JdbcTemplate jdbcTemplate) {
|
public TemplateMapper(final JdbcTemplate jdbcTemplate) {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " s.id, s.name from m_hook_templates s ";
|
return " s.id, s.name from m_hook_templates s ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HookTemplateData mapRow(final ResultSet rs,
|
public HookTemplateData mapRow(final ResultSet rs,
|
||||||
@SuppressWarnings("unused") final int rowNum)
|
@SuppressWarnings("unused") final int rowNum)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
|
|
||||||
final Long id = rs.getLong("id");
|
final Long id = rs.getLong("id");
|
||||||
final String name = rs.getString("name");
|
final String name = rs.getString("name");
|
||||||
final List<Field> schema = retrieveSchema(id);
|
final List<Field> schema = retrieveSchema(id);
|
||||||
|
|
||||||
return HookTemplateData.instance(id, name, schema);
|
return HookTemplateData.instance(id, name, schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Field> retrieveSchema(final Long templateId) {
|
private List<Field> retrieveSchema(final Long templateId) {
|
||||||
|
|
||||||
final TemplateSchemaMapper rm = new TemplateSchemaMapper();
|
final TemplateSchemaMapper rm = new TemplateSchemaMapper();
|
||||||
final String sql = "select " + rm.schema()
|
final String sql = "select " + rm.schema()
|
||||||
+ " where s.id= ? order by hs.field_name ";
|
+ " where s.id= ? order by hs.field_name ";
|
||||||
|
|
||||||
final List<Field> fields = this.jdbcTemplate.query(sql, rm,
|
final List<Field> fields = this.jdbcTemplate.query(sql, rm,
|
||||||
new Object[] { templateId });
|
new Object[]{templateId});
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class TemplateSchemaMapper implements RowMapper<Field> {
|
private static final class TemplateSchemaMapper implements RowMapper<Field> {
|
||||||
|
|
||||||
public String schema() {
|
public String schema() {
|
||||||
return " hs.field_type, hs.field_name, hs.placeholder, hs.optional from m_hook_templates s "
|
return " hs.field_type, hs.field_name, hs.placeholder, hs.optional from m_hook_templates s "
|
||||||
+ " inner join m_hook_schema hs on s.id = hs.hook_template_id ";
|
+ " inner join m_hook_schema hs on s.id = hs.hook_template_id ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Field mapRow(final ResultSet rs,
|
public Field mapRow(final ResultSet rs,
|
||||||
@SuppressWarnings("unused") final int rowNum)
|
@SuppressWarnings("unused") final int rowNum)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
final String fieldName = rs.getString("field_name");
|
final String fieldName = rs.getString("field_name");
|
||||||
final String fieldType = rs.getString("field_type");
|
final String fieldType = rs.getString("field_type");
|
||||||
final Boolean optional = rs.getBoolean("optional");
|
final Boolean optional = rs.getBoolean("optional");
|
||||||
final String placeholder = rs.getString("placeholder");
|
final String placeholder = rs.getString("placeholder");
|
||||||
return Field
|
return Field
|
||||||
.fromSchema(fieldType, fieldName, optional, placeholder);
|
.fromSchema(fieldType, fieldName, optional, placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+275
-264
@@ -5,22 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.infrastructure.hooks.service;
|
package org.mifosplatform.infrastructure.hooks.service;
|
||||||
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.actionNameParamName;
|
import com.google.gson.JsonArray;
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.configParamName;
|
import com.google.gson.JsonObject;
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.contentTypeName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.entityNameParamName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.eventsParamName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.nameParamName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.payloadURLName;
|
|
||||||
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.webTemplateName;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
@@ -29,313 +15,338 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
|||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.Hook;
|
import org.mifosplatform.infrastructure.hooks.domain.*;
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookConfiguration;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookRepository;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookResource;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookTemplate;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.HookTemplateRepository;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.domain.Schema;
|
|
||||||
import org.mifosplatform.infrastructure.hooks.exception.HookNotFoundException;
|
import org.mifosplatform.infrastructure.hooks.exception.HookNotFoundException;
|
||||||
import org.mifosplatform.infrastructure.hooks.exception.HookTemplateNotFoundException;
|
import org.mifosplatform.infrastructure.hooks.exception.HookTemplateNotFoundException;
|
||||||
import org.mifosplatform.infrastructure.hooks.processor.ProcessorHelper;
|
import org.mifosplatform.infrastructure.hooks.processor.ProcessorHelper;
|
||||||
import org.mifosplatform.infrastructure.hooks.processor.WebHookService;
|
import org.mifosplatform.infrastructure.hooks.processor.WebHookService;
|
||||||
import org.mifosplatform.infrastructure.hooks.serialization.HookCommandFromApiJsonDeserializer;
|
import org.mifosplatform.infrastructure.hooks.serialization.HookCommandFromApiJsonDeserializer;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.mifosplatform.template.domain.Template;
|
||||||
|
import org.mifosplatform.template.domain.TemplateRepository;
|
||||||
|
import org.mifosplatform.template.exception.TemplateNotFoundException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
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;
|
import retrofit.RetrofitError;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import java.util.*;
|
||||||
import com.google.gson.JsonObject;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import static org.mifosplatform.infrastructure.hooks.api.HookApiConstants.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class HookWritePlatformServiceJpaRepositoryImpl implements
|
public class HookWritePlatformServiceJpaRepositoryImpl
|
||||||
HookWritePlatformService {
|
implements
|
||||||
|
HookWritePlatformService {
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final HookRepository hookRepository;
|
private final HookRepository hookRepository;
|
||||||
private final HookTemplateRepository hookTemplateRepository;
|
private final HookTemplateRepository hookTemplateRepository;
|
||||||
private final HookCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
private final TemplateRepository ugdTemplateRepository;
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final HookCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HookWritePlatformServiceJpaRepositoryImpl(
|
public HookWritePlatformServiceJpaRepositoryImpl(
|
||||||
final PlatformSecurityContext context,
|
final PlatformSecurityContext context,
|
||||||
final HookRepository hookRepository,
|
final HookRepository hookRepository,
|
||||||
final HookTemplateRepository hookTemplateRepository,
|
final HookTemplateRepository hookTemplateRepository,
|
||||||
final HookCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
final TemplateRepository ugdTemplateRepository,
|
||||||
final FromJsonHelper fromApiJsonHelper) {
|
final HookCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||||
this.context = context;
|
final FromJsonHelper fromApiJsonHelper) {
|
||||||
this.hookRepository = hookRepository;
|
this.context = context;
|
||||||
this.hookTemplateRepository = hookTemplateRepository;
|
this.hookRepository = hookRepository;
|
||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.hookTemplateRepository = hookTemplateRepository;
|
||||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
this.ugdTemplateRepository = ugdTemplateRepository;
|
||||||
}
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
|
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(value = "hooks", allEntries = true)
|
@CacheEvict(value = "hooks", allEntries = true)
|
||||||
public CommandProcessingResult createHook(final JsonCommand command) {
|
public CommandProcessingResult createHook(final JsonCommand command) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||||
|
|
||||||
final HookTemplate template = retrieveHookTemplateBy(command
|
final HookTemplate template = retrieveHookTemplateBy(command
|
||||||
.stringValueOfParameterNamed(nameParamName));
|
.stringValueOfParameterNamed(nameParamName));
|
||||||
final String configJson = command.jsonFragment(configParamName);
|
final String configJson = command.jsonFragment(configParamName);
|
||||||
final Set<HookConfiguration> config = assembleConfig(
|
final Set<HookConfiguration> config = assembleConfig(
|
||||||
command.mapValueOfParameterNamed(configJson), template);
|
command.mapValueOfParameterNamed(configJson), template);
|
||||||
final JsonArray events = command
|
final JsonArray events = command
|
||||||
.arrayOfParameterNamed(eventsParamName);
|
.arrayOfParameterNamed(eventsParamName);
|
||||||
final Set<HookResource> allEvents = assembleSetOfEvents(events);
|
final Set<HookResource> allEvents = assembleSetOfEvents(events);
|
||||||
final Hook hook = Hook.fromJson(command, template, config,
|
Template ugdTemplate = null;
|
||||||
allEvents);
|
if (command.hasParameter(templateIdParamName)) {
|
||||||
|
final Long ugdTemplateId = command
|
||||||
|
.longValueOfParameterNamed(templateIdParamName);
|
||||||
|
ugdTemplate = this.ugdTemplateRepository.findOne(ugdTemplateId);
|
||||||
|
if (ugdTemplate == null) {
|
||||||
|
throw new TemplateNotFoundException(ugdTemplateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Hook hook = Hook.fromJson(command, template, config,
|
||||||
|
allEvents, ugdTemplate);
|
||||||
|
|
||||||
validateHookRules(template, config, allEvents);
|
validateHookRules(template, config, allEvents);
|
||||||
|
|
||||||
this.hookRepository.save(hook);
|
this.hookRepository.save(hook);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder()
|
return new CommandProcessingResultBuilder()
|
||||||
.withCommandId(command.commandId())
|
.withCommandId(command.commandId())
|
||||||
.withEntityId(hook.getId()).build();
|
.withEntityId(hook.getId()).build();
|
||||||
} catch (final DataIntegrityViolationException dve) {
|
} catch (final DataIntegrityViolationException dve) {
|
||||||
handleHookDataIntegrityIssues(command, dve);
|
handleHookDataIntegrityIssues(command, dve);
|
||||||
return CommandProcessingResult.empty();
|
return CommandProcessingResult.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(value = "hooks", allEntries = true)
|
@CacheEvict(value = "hooks", allEntries = true)
|
||||||
public CommandProcessingResult updateHook(final Long hookId,
|
public CommandProcessingResult updateHook(final Long hookId,
|
||||||
final JsonCommand command) {
|
final JsonCommand command) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||||
|
|
||||||
final Hook hook = retrieveHookBy(hookId);
|
final Hook hook = retrieveHookBy(hookId);
|
||||||
final HookTemplate template = hook.getHookTemplate();
|
final HookTemplate template = hook.getHookTemplate();
|
||||||
final Map<String, Object> changes = hook.update(command);
|
final Map<String, Object> changes = hook.update(command);
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
|
|
||||||
if (changes.containsKey(eventsParamName)) {
|
if (changes.containsKey(templateIdParamName)) {
|
||||||
final Set<HookResource> events = assembleSetOfEvents(command
|
final Long ugdTemplateId = command
|
||||||
.arrayOfParameterNamed(eventsParamName));
|
.longValueOfParameterNamed(templateIdParamName);
|
||||||
final boolean updated = hook.updateEvents(events);
|
final Template ugdTemplate = this.ugdTemplateRepository
|
||||||
if (!updated) {
|
.findOne(ugdTemplateId);
|
||||||
changes.remove(eventsParamName);
|
if (ugdTemplate == null) {
|
||||||
}
|
changes.remove(templateIdParamName);
|
||||||
}
|
throw new TemplateNotFoundException(ugdTemplateId);
|
||||||
|
}
|
||||||
|
hook.updateUgdTemplate(ugdTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
if (changes.containsKey(configParamName)) {
|
if (changes.containsKey(eventsParamName)) {
|
||||||
final String configJson = command
|
final Set<HookResource> events = assembleSetOfEvents(command
|
||||||
.jsonFragment(configParamName);
|
.arrayOfParameterNamed(eventsParamName));
|
||||||
final Set<HookConfiguration> config = assembleConfig(
|
final boolean updated = hook.updateEvents(events);
|
||||||
command.mapValueOfParameterNamed(configJson),
|
if (!updated) {
|
||||||
template);
|
changes.remove(eventsParamName);
|
||||||
final boolean updated = hook.updateConfig(config);
|
}
|
||||||
if (!updated) {
|
}
|
||||||
changes.remove(configParamName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hookRepository.saveAndFlush(hook);
|
if (changes.containsKey(configParamName)) {
|
||||||
}
|
final String configJson = command
|
||||||
|
.jsonFragment(configParamName);
|
||||||
|
final Set<HookConfiguration> config = assembleConfig(
|
||||||
|
command.mapValueOfParameterNamed(configJson),
|
||||||
|
template);
|
||||||
|
final boolean updated = hook.updateConfig(config);
|
||||||
|
if (!updated) {
|
||||||
|
changes.remove(configParamName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
this.hookRepository.saveAndFlush(hook);
|
||||||
.withCommandId(command.commandId()) //
|
}
|
||||||
.withEntityId(hookId) //
|
|
||||||
.with(changes) //
|
|
||||||
.build();
|
|
||||||
} catch (final DataIntegrityViolationException dve) {
|
|
||||||
handleHookDataIntegrityIssues(command, dve);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
return new CommandProcessingResultBuilder() //
|
||||||
@Override
|
.withCommandId(command.commandId()) //
|
||||||
@CacheEvict(value = "hooks", allEntries = true)
|
.withEntityId(hookId) //
|
||||||
public CommandProcessingResult deleteHook(final Long hookId) {
|
.with(changes) //
|
||||||
|
.build();
|
||||||
|
} catch (final DataIntegrityViolationException dve) {
|
||||||
|
handleHookDataIntegrityIssues(command, dve);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.context.authenticatedUser();
|
@Transactional
|
||||||
|
@Override
|
||||||
|
@CacheEvict(value = "hooks", allEntries = true)
|
||||||
|
public CommandProcessingResult deleteHook(final Long hookId) {
|
||||||
|
|
||||||
final Hook hook = retrieveHookBy(hookId);
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
try {
|
final Hook hook = retrieveHookBy(hookId);
|
||||||
this.hookRepository.delete(hook);
|
|
||||||
this.hookRepository.flush();
|
|
||||||
} catch (final DataIntegrityViolationException e) {
|
|
||||||
throw new PlatformDataIntegrityException(
|
|
||||||
"error.msg.unknown.data.integrity.issue",
|
|
||||||
"Unknown data integrity issue with resource: "
|
|
||||||
+ e.getMostSpecificCause());
|
|
||||||
}
|
|
||||||
return new CommandProcessingResultBuilder().withEntityId(hookId)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hook retrieveHookBy(final Long hookId) {
|
try {
|
||||||
final Hook hook = this.hookRepository.findOne(hookId);
|
this.hookRepository.delete(hook);
|
||||||
if (hook == null) {
|
this.hookRepository.flush();
|
||||||
throw new HookNotFoundException(hookId.toString());
|
} catch (final DataIntegrityViolationException e) {
|
||||||
}
|
throw new PlatformDataIntegrityException(
|
||||||
return hook;
|
"error.msg.unknown.data.integrity.issue",
|
||||||
}
|
"Unknown data integrity issue with resource: "
|
||||||
|
+ e.getMostSpecificCause());
|
||||||
|
}
|
||||||
|
return new CommandProcessingResultBuilder().withEntityId(hookId)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private HookTemplate retrieveHookTemplateBy(final String templateName) {
|
private Hook retrieveHookBy(final Long hookId) {
|
||||||
final HookTemplate template = this.hookTemplateRepository
|
final Hook hook = this.hookRepository.findOne(hookId);
|
||||||
.findOne(templateName);
|
if (hook == null) {
|
||||||
if (template == null) {
|
throw new HookNotFoundException(hookId.toString());
|
||||||
throw new HookTemplateNotFoundException(templateName);
|
}
|
||||||
}
|
return hook;
|
||||||
return template;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Set<HookConfiguration> assembleConfig(
|
private HookTemplate retrieveHookTemplateBy(final String templateName) {
|
||||||
final Map<String, String> hookConfig, final HookTemplate template) {
|
final HookTemplate template = this.hookTemplateRepository
|
||||||
|
.findOne(templateName);
|
||||||
|
if (template == null) {
|
||||||
|
throw new HookTemplateNotFoundException(templateName);
|
||||||
|
}
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
final Set<HookConfiguration> configuration = new HashSet<>();
|
private Set<HookConfiguration> assembleConfig(
|
||||||
final Set<Schema> fields = template.getSchema();
|
final Map<String, String> hookConfig, final HookTemplate template) {
|
||||||
|
|
||||||
for (final Entry<String, String> configEntry : hookConfig.entrySet()) {
|
final Set<HookConfiguration> configuration = new HashSet<>();
|
||||||
for (final Schema field : fields) {
|
final Set<Schema> fields = template.getSchema();
|
||||||
final String fieldName = field.getFieldName();
|
|
||||||
if (fieldName.equalsIgnoreCase(configEntry.getKey())) {
|
|
||||||
|
|
||||||
final HookConfiguration config = HookConfiguration
|
for (final Entry<String, String> configEntry : hookConfig.entrySet()) {
|
||||||
.createNewWithoutHook(field.getFieldType(),
|
for (final Schema field : fields) {
|
||||||
configEntry.getKey(),
|
final String fieldName = field.getFieldName();
|
||||||
configEntry.getValue());
|
if (fieldName.equalsIgnoreCase(configEntry.getKey())) {
|
||||||
configuration.add(config);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
final HookConfiguration config = HookConfiguration
|
||||||
|
.createNewWithoutHook(field.getFieldType(),
|
||||||
|
configEntry.getKey(),
|
||||||
|
configEntry.getValue());
|
||||||
|
configuration.add(config);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return configuration;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Set<HookResource> assembleSetOfEvents(final JsonArray eventsArray) {
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
final Set<HookResource> allEvents = new HashSet<>();
|
private Set<HookResource> assembleSetOfEvents(final JsonArray eventsArray) {
|
||||||
|
|
||||||
for (int i = 0; i < eventsArray.size(); i++) {
|
final Set<HookResource> allEvents = new HashSet<>();
|
||||||
|
|
||||||
final JsonObject eventElement = eventsArray.get(i)
|
for (int i = 0; i < eventsArray.size(); i++) {
|
||||||
.getAsJsonObject();
|
|
||||||
|
|
||||||
final String entityName = this.fromApiJsonHelper
|
final JsonObject eventElement = eventsArray.get(i)
|
||||||
.extractStringNamed(entityNameParamName, eventElement);
|
.getAsJsonObject();
|
||||||
final String actionName = this.fromApiJsonHelper
|
|
||||||
.extractStringNamed(actionNameParamName, eventElement);
|
|
||||||
final HookResource event = HookResource.createNewWithoutHook(
|
|
||||||
entityName, actionName);
|
|
||||||
allEvents.add(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return allEvents;
|
final String entityName = this.fromApiJsonHelper
|
||||||
}
|
.extractStringNamed(entityNameParamName, eventElement);
|
||||||
|
final String actionName = this.fromApiJsonHelper
|
||||||
|
.extractStringNamed(actionNameParamName, eventElement);
|
||||||
|
final HookResource event = HookResource.createNewWithoutHook(
|
||||||
|
entityName, actionName);
|
||||||
|
allEvents.add(event);
|
||||||
|
}
|
||||||
|
|
||||||
private void validateHookRules(final HookTemplate template,
|
return allEvents;
|
||||||
final Set<HookConfiguration> config, Set<HookResource> events) {
|
}
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
private void validateHookRules(final HookTemplate template,
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
final Set<HookConfiguration> config, Set<HookResource> events) {
|
||||||
dataValidationErrors).resource("hook");
|
|
||||||
|
|
||||||
if (!template.getName().equalsIgnoreCase(webTemplateName)
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
&& this.hookRepository.findOneByTemplateId(template.getId()) != null) {
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
||||||
final String errorMessage = "multiple.non.web.template.hooks.not.supported";
|
dataValidationErrors).resource("hook");
|
||||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
|
||||||
errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final HookConfiguration conf : config) {
|
if (!template.getName().equalsIgnoreCase(webTemplateName)
|
||||||
final String fieldValue = conf.getFieldValue();
|
&& this.hookRepository.findOneByTemplateId(template.getId()) != null) {
|
||||||
if (conf.getFieldName().equals(contentTypeName)) {
|
final String errorMessage = "multiple.non.web.template.hooks.not.supported";
|
||||||
if (!(fieldValue.equalsIgnoreCase("json") || fieldValue
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||||
.equalsIgnoreCase("form"))) {
|
errorMessage);
|
||||||
final String errorMessage = "content.type.must.be.json.or.form";
|
}
|
||||||
baseDataValidator.reset()
|
|
||||||
.failWithCodeNoParameterAddedToErrorCode(
|
|
||||||
errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conf.getFieldName().equals(payloadURLName)) {
|
for (final HookConfiguration conf : config) {
|
||||||
try {
|
final String fieldValue = conf.getFieldValue();
|
||||||
final WebHookService service = ProcessorHelper
|
if (conf.getFieldName().equals(contentTypeName)) {
|
||||||
.createWebHookService(fieldValue);
|
if (!(fieldValue.equalsIgnoreCase("json") || fieldValue
|
||||||
service.sendEmptyRequest();
|
.equalsIgnoreCase("form"))) {
|
||||||
} catch (RetrofitError re) {
|
final String errorMessage = "content.type.must.be.json.or.form";
|
||||||
// Swallow error if it's because of method not supported or
|
baseDataValidator.reset()
|
||||||
// if url throws 404 - required for integration test,
|
.failWithCodeNoParameterAddedToErrorCode(
|
||||||
// url generated on 1st POST request
|
errorMessage);
|
||||||
if (re.getResponse() == null) {
|
}
|
||||||
String errorMessage = "url.invalid";
|
}
|
||||||
baseDataValidator.reset()
|
|
||||||
.failWithCodeNoParameterAddedToErrorCode(
|
|
||||||
errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events == null || events.isEmpty()) {
|
if (conf.getFieldName().equals(payloadURLName)) {
|
||||||
final String errorMessage = "registered.events.cannot.be.empty";
|
try {
|
||||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
final WebHookService service = ProcessorHelper
|
||||||
errorMessage);
|
.createWebHookService(fieldValue);
|
||||||
}
|
service.sendEmptyRequest();
|
||||||
|
} catch (RetrofitError re) {
|
||||||
|
// Swallow error if it's because of method not supported or
|
||||||
|
// if url throws 404 - required for integration test,
|
||||||
|
// url generated on 1st POST request
|
||||||
|
if (re.getResponse() == null) {
|
||||||
|
String errorMessage = "url.invalid";
|
||||||
|
baseDataValidator.reset()
|
||||||
|
.failWithCodeNoParameterAddedToErrorCode(
|
||||||
|
errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final Set<Schema> fields = template.getSchema();
|
if (events == null || events.isEmpty()) {
|
||||||
for (final Schema field : fields) {
|
final String errorMessage = "registered.events.cannot.be.empty";
|
||||||
if (!field.isOptional()) {
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||||
boolean found = false;
|
errorMessage);
|
||||||
for (final HookConfiguration conf : config) {
|
}
|
||||||
if (field.getFieldName().equals(conf.getFieldName())) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
final String errorMessage = "required.config.field."
|
|
||||||
+ "not.provided";
|
|
||||||
baseDataValidator.reset().value(field.getFieldName())
|
|
||||||
.failWithCodeNoParameterAddedToErrorCode(
|
|
||||||
errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dataValidationErrors.isEmpty()) {
|
final Set<Schema> fields = template.getSchema();
|
||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
for (final Schema field : fields) {
|
||||||
}
|
if (!field.isOptional()) {
|
||||||
}
|
boolean found = false;
|
||||||
|
for (final HookConfiguration conf : config) {
|
||||||
|
if (field.getFieldName().equals(conf.getFieldName())) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
final String errorMessage = "required.config.field."
|
||||||
|
+ "not.provided";
|
||||||
|
baseDataValidator
|
||||||
|
.reset()
|
||||||
|
.value(field.getFieldName())
|
||||||
|
.failWithCodeNoParameterAddedToErrorCode(
|
||||||
|
errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleHookDataIntegrityIssues(final JsonCommand command,
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
final DataIntegrityViolationException dve) {
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
final Throwable realCause = dve.getMostSpecificCause();
|
}
|
||||||
if (realCause.getMessage().contains("hook_name")) {
|
}
|
||||||
final String name = command.stringValueOfParameterNamed("name");
|
|
||||||
throw new PlatformDataIntegrityException(
|
|
||||||
"error.msg.hook.duplicate.name", "A hook with name '"
|
|
||||||
+ name + "' already exists", "name", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new PlatformDataIntegrityException(
|
private void handleHookDataIntegrityIssues(final JsonCommand command,
|
||||||
"error.msg.unknown.data.integrity.issue",
|
final DataIntegrityViolationException dve) {
|
||||||
"Unknown data integrity issue with resource: "
|
final Throwable realCause = dve.getMostSpecificCause();
|
||||||
+ realCause.getMessage());
|
if (realCause.getMessage().contains("hook_name")) {
|
||||||
}
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
|
throw new PlatformDataIntegrityException(
|
||||||
|
"error.msg.hook.duplicate.name", "A hook with name '"
|
||||||
|
+ name + "' already exists", "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new PlatformDataIntegrityException(
|
||||||
|
"error.msg.unknown.data.integrity.issue",
|
||||||
|
"Unknown data integrity issue with resource: "
|
||||||
|
+ realCause.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import com.google.gson.JsonArray;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_template", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
|
@Table(name = "m_template", uniqueConstraints = {@UniqueConstraint(columnNames = {"name"}, name = "unq_name")})
|
||||||
public class Template extends AbstractPersistable<Long> {
|
public class Template extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
@Column(name = "name", nullable = false, unique = true)
|
@Column(name = "name", nullable = false, unique = true)
|
||||||
@@ -49,7 +49,8 @@ public class Template extends AbstractPersistable<Long> {
|
|||||||
@OneToMany(targetEntity = TemplateMapper.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
@OneToMany(targetEntity = TemplateMapper.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private List<TemplateMapper> mappers;
|
private List<TemplateMapper> mappers;
|
||||||
|
|
||||||
public Template(final String name, final String text, final TemplateEntity entity, final TemplateType type,
|
public Template(final String name, final String text,
|
||||||
|
final TemplateEntity entity, final TemplateType type,
|
||||||
final List<TemplateMapper> mappers) {
|
final List<TemplateMapper> mappers) {
|
||||||
this.name = StringUtils.defaultIfEmpty(name, null);
|
this.name = StringUtils.defaultIfEmpty(name, null);
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
@@ -65,16 +66,29 @@ public class Template extends AbstractPersistable<Long> {
|
|||||||
public static Template fromJson(final JsonCommand command) {
|
public static Template fromJson(final JsonCommand command) {
|
||||||
final String name = command.stringValueOfParameterNamed("name");
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
final String text = command.stringValueOfParameterNamed("text");
|
final String text = command.stringValueOfParameterNamed("text");
|
||||||
final TemplateEntity entity = TemplateEntity.values()[command.integerValueSansLocaleOfParameterNamed("entity")];
|
final TemplateEntity entity = TemplateEntity.values()[command
|
||||||
final TemplateType type = TemplateType.values()[command.integerValueSansLocaleOfParameterNamed("type")];
|
.integerValueSansLocaleOfParameterNamed("entity")];
|
||||||
|
final int templateTypeId = command
|
||||||
|
.integerValueSansLocaleOfParameterNamed("type");
|
||||||
|
TemplateType type = null;
|
||||||
|
switch (templateTypeId) {
|
||||||
|
case 0 :
|
||||||
|
type = TemplateType.DOCUMENT;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
type = TemplateType.SMS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
final JsonArray array = command.arrayOfParameterNamed("mappers");
|
final JsonArray array = command.arrayOfParameterNamed("mappers");
|
||||||
|
|
||||||
final List<TemplateMapper> mappersList = new ArrayList<>();
|
final List<TemplateMapper> mappersList = new ArrayList<>();
|
||||||
|
|
||||||
for (final JsonElement element : array) {
|
for (final JsonElement element : array) {
|
||||||
mappersList.add(new TemplateMapper(element.getAsJsonObject().get("mappersorder").getAsInt(), element.getAsJsonObject()
|
mappersList.add(new TemplateMapper(element.getAsJsonObject()
|
||||||
.get("mapperskey").getAsString(), element.getAsJsonObject().get("mappersvalue").getAsString()));
|
.get("mappersorder").getAsInt(), element.getAsJsonObject()
|
||||||
|
.get("mapperskey").getAsString(), element.getAsJsonObject()
|
||||||
|
.get("mappersvalue").getAsString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Template(name, text, entity, type, mappersList);
|
return new Template(name, text, entity, type, mappersList);
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
public enum TemplateType {
|
public enum TemplateType {
|
||||||
|
|
||||||
@SerializedName("Document")
|
@SerializedName("Document")
|
||||||
DOCUMENT(0, "Document");
|
DOCUMENT(0, "Document"), @SerializedName("SMS")
|
||||||
|
SMS(2, "SMS");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @SerializedName("E-Mail") EMAIL(1, "E-Mail"),
|
* @SerializedName("E-Mail") EMAIL(1, "E-Mail")
|
||||||
* @SerializedName("SMS") SMS(2, "SMS");
|
|
||||||
*/
|
*/
|
||||||
private int id;
|
private int id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
+32
-10
@@ -44,7 +44,9 @@ public class JpaTemplateDomainService implements TemplateDomainService {
|
|||||||
@Override
|
@Override
|
||||||
public Template findOneById(final Long id) {
|
public Template findOneById(final Long id) {
|
||||||
final Template template = this.templateRepository.findOne(id);
|
final Template template = this.templateRepository.findOne(id);
|
||||||
if (template == null) { throw new TemplateNotFoundException(id); }
|
if (template == null) {
|
||||||
|
throw new TemplateNotFoundException(id);
|
||||||
|
}
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +60,14 @@ public class JpaTemplateDomainService implements TemplateDomainService {
|
|||||||
final Template template = Template.fromJson(command);
|
final Template template = Template.fromJson(command);
|
||||||
|
|
||||||
this.templateRepository.saveAndFlush(template);
|
this.templateRepository.saveAndFlush(template);
|
||||||
return new CommandProcessingResultBuilder().withEntityId(template.getId()).build();
|
return new CommandProcessingResultBuilder().withEntityId(
|
||||||
|
template.getId()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult updateTemplate(final Long templateId, final JsonCommand command) {
|
public CommandProcessingResult updateTemplate(final Long templateId,
|
||||||
|
final JsonCommand command) {
|
||||||
// FIXME - no validation here of the data in the command object, is
|
// FIXME - no validation here of the data in the command object, is
|
||||||
// name, text populated etc
|
// name, text populated etc
|
||||||
// FIXME - handle cases where data integrity constraints are fired from
|
// FIXME - handle cases where data integrity constraints are fired from
|
||||||
@@ -72,20 +76,36 @@ public class JpaTemplateDomainService implements TemplateDomainService {
|
|||||||
final Template template = findOneById(templateId);
|
final Template template = findOneById(templateId);
|
||||||
template.setName(command.stringValueOfParameterNamed(PROPERTY_NAME));
|
template.setName(command.stringValueOfParameterNamed(PROPERTY_NAME));
|
||||||
template.setText(command.stringValueOfParameterNamed(PROPERTY_TEXT));
|
template.setText(command.stringValueOfParameterNamed(PROPERTY_TEXT));
|
||||||
template.setEntity(TemplateEntity.values()[command.integerValueSansLocaleOfParameterNamed(PROPERTY_ENTITY)]);
|
template.setEntity(TemplateEntity.values()[command
|
||||||
template.setType(TemplateType.values()[command.integerValueSansLocaleOfParameterNamed(PROPERTY_TYPE)]);
|
.integerValueSansLocaleOfParameterNamed(PROPERTY_ENTITY)]);
|
||||||
|
final int templateTypeId = command
|
||||||
|
.integerValueSansLocaleOfParameterNamed(PROPERTY_TYPE);
|
||||||
|
TemplateType type = null;
|
||||||
|
switch (templateTypeId) {
|
||||||
|
case 0 :
|
||||||
|
type = TemplateType.DOCUMENT;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
type = TemplateType.SMS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
template.setType(type);
|
||||||
|
|
||||||
final JsonArray array = command.arrayOfParameterNamed("mappers");
|
final JsonArray array = command.arrayOfParameterNamed("mappers");
|
||||||
final List<TemplateMapper> mappersList = new ArrayList<>();
|
final List<TemplateMapper> mappersList = new ArrayList<>();
|
||||||
for (final JsonElement element : array) {
|
for (final JsonElement element : array) {
|
||||||
mappersList.add(new TemplateMapper(element.getAsJsonObject().get("mappersorder").getAsInt(), element.getAsJsonObject()
|
mappersList.add(new TemplateMapper(element.getAsJsonObject()
|
||||||
.get("mapperskey").getAsString(), element.getAsJsonObject().get("mappersvalue").getAsString()));
|
.get("mappersorder").getAsInt(), element.getAsJsonObject()
|
||||||
|
.get("mapperskey").getAsString(), element.getAsJsonObject()
|
||||||
|
.get("mappersvalue").getAsString()));
|
||||||
}
|
}
|
||||||
template.setMappers(mappersList);
|
template.setMappers(mappersList);
|
||||||
|
|
||||||
this.templateRepository.saveAndFlush(template);
|
this.templateRepository.saveAndFlush(template);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(template.getId()).build();
|
return new CommandProcessingResultBuilder()
|
||||||
|
.withCommandId(command.commandId())
|
||||||
|
.withEntityId(template.getId()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -95,7 +115,8 @@ public class JpaTemplateDomainService implements TemplateDomainService {
|
|||||||
|
|
||||||
this.templateRepository.delete(template);
|
this.templateRepository.delete(template);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withEntityId(templateId).build();
|
return new CommandProcessingResultBuilder().withEntityId(templateId)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -105,7 +126,8 @@ public class JpaTemplateDomainService implements TemplateDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Template> getAllByEntityAndType(final TemplateEntity entity, final TemplateType type) {
|
public List<Template> getAllByEntityAndType(final TemplateEntity entity,
|
||||||
|
final TemplateType type) {
|
||||||
|
|
||||||
return this.templateRepository.findByEntityAndType(entity, type);
|
return this.templateRepository.findByEntityAndType(entity, type);
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-20
@@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.mifosplatform.template.domain.Template;
|
import org.mifosplatform.template.domain.Template;
|
||||||
import org.mifosplatform.template.domain.TemplateFunctions;
|
import org.mifosplatform.template.domain.TemplateFunctions;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@@ -35,23 +36,32 @@ import com.github.mustachejava.MustacheFactory;
|
|||||||
@Service
|
@Service
|
||||||
public class TemplateMergeService {
|
public class TemplateMergeService {
|
||||||
|
|
||||||
// private final FromJsonHelper fromApiJsonHelper;
|
// private final FromJsonHelper fromApiJsonHelper;
|
||||||
private Map<String, Object> scopes;
|
private Map<String, Object> scopes;
|
||||||
|
private String authToken;
|
||||||
|
|
||||||
// @Autowired
|
// @Autowired
|
||||||
// public TemplateMergeService(final FromJsonHelper fromApiJsonHelper) {
|
// public TemplateMergeService(final FromJsonHelper fromApiJsonHelper) {
|
||||||
// this.fromApiJsonHelper = fromApiJsonHelper;
|
// this.fromApiJsonHelper = fromApiJsonHelper;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public String compile(final Template template, final Map<String, Object> scopes) throws MalformedURLException, IOException {
|
public void setAuthToken(final String authToken) {
|
||||||
|
this.authToken = authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String compile(final Template template,
|
||||||
|
final Map<String, Object> scopes) throws MalformedURLException,
|
||||||
|
IOException {
|
||||||
|
|
||||||
this.scopes = scopes;
|
this.scopes = scopes;
|
||||||
this.scopes.put("static", new TemplateFunctions());
|
this.scopes.put("static", new TemplateFunctions());
|
||||||
|
|
||||||
final MustacheFactory mf = new DefaultMustacheFactory();
|
final MustacheFactory mf = new DefaultMustacheFactory();
|
||||||
final Mustache mustache = mf.compile(new StringReader(template.getText()), template.getName());
|
final Mustache mustache = mf.compile(
|
||||||
|
new StringReader(template.getText()), template.getName());
|
||||||
|
|
||||||
final Map<String, Object> mappers = getCompiledMapFromMappers(template.getMappersAsMap());
|
final Map<String, Object> mappers = getCompiledMapFromMappers(template
|
||||||
|
.getMappersAsMap());
|
||||||
this.scopes.putAll(mappers);
|
this.scopes.putAll(mappers);
|
||||||
|
|
||||||
final StringWriter stringWriter = new StringWriter();
|
final StringWriter stringWriter = new StringWriter();
|
||||||
@@ -60,14 +70,16 @@ public class TemplateMergeService {
|
|||||||
return stringWriter.toString();
|
return stringWriter.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> getCompiledMapFromMappers(final Map<String, String> data) {
|
private Map<String, Object> getCompiledMapFromMappers(
|
||||||
|
final Map<String, String> data) {
|
||||||
|
|
||||||
final MustacheFactory mf = new DefaultMustacheFactory();
|
final MustacheFactory mf = new DefaultMustacheFactory();
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
for (final Map.Entry<String, String> entry : data.entrySet()) {
|
for (final Map.Entry<String, String> entry : data.entrySet()) {
|
||||||
|
|
||||||
final Mustache mappersMustache = mf.compile(new StringReader(entry.getValue()), "");
|
final Mustache mappersMustache = mf.compile(new StringReader(
|
||||||
|
entry.getValue()), "");
|
||||||
final StringWriter stringWriter = new StringWriter();
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
|
||||||
mappersMustache.execute(stringWriter, this.scopes);
|
mappersMustache.execute(stringWriter, this.scopes);
|
||||||
@@ -88,11 +100,13 @@ public class TemplateMergeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Map<String, Object> getMapFromUrl(final String url) throws MalformedURLException, IOException {
|
private Map<String, Object> getMapFromUrl(final String url)
|
||||||
|
throws MalformedURLException, IOException {
|
||||||
|
|
||||||
final HttpURLConnection connection = getConnection(url);
|
final HttpURLConnection connection = getConnection(url);
|
||||||
|
|
||||||
final String response = getStringFromInputStream(connection.getInputStream());
|
final String response = getStringFromInputStream(connection
|
||||||
|
.getInputStream());
|
||||||
HashMap<String, Object> result = new HashMap<>();
|
HashMap<String, Object> result = new HashMap<>();
|
||||||
if (connection.getContentType().equals("text/plain")) {
|
if (connection.getContentType().equals("text/plain")) {
|
||||||
result.put("src", response);
|
result.put("src", response);
|
||||||
@@ -104,20 +118,29 @@ public class TemplateMergeService {
|
|||||||
|
|
||||||
private HttpURLConnection getConnection(final String url) {
|
private HttpURLConnection getConnection(final String url) {
|
||||||
|
|
||||||
final String name = SecurityContextHolder.getContext().getAuthentication().getName();
|
if (this.authToken == null) {
|
||||||
final String password = SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
|
final String name = SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication().getName();
|
||||||
|
final String password = SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication().getCredentials().toString();
|
||||||
|
|
||||||
Authenticator.setDefault(new Authenticator() {
|
Authenticator.setDefault(new Authenticator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
protected PasswordAuthentication getPasswordAuthentication() {
|
||||||
return new PasswordAuthentication(name, password.toCharArray());
|
return new PasswordAuthentication(name, password
|
||||||
}
|
.toCharArray());
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
HttpURLConnection connection = null;
|
HttpURLConnection connection = null;
|
||||||
try {
|
try {
|
||||||
connection = (HttpURLConnection) new URL(url).openConnection();
|
connection = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
if (this.authToken != null) {
|
||||||
|
connection.setRequestProperty("Authorization", "Basic "
|
||||||
|
+ this.authToken);
|
||||||
|
}
|
||||||
TrustModifier.relaxHostChecking(connection);
|
TrustModifier.relaxHostChecking(connection);
|
||||||
|
|
||||||
connection.setDoInput(true);
|
connection.setDoInput(true);
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `m_hook` ADD COLUMN `ugd_template_id` bigint(20) NOT NULL;
|
||||||
|
ALTER TABLE `m_hook` ADD CONSTRAINT `fk_ugd_template_id` FOREIGN KEY (`ugd_template_id`) REFERENCES `m_template` (`id`);
|
||||||
Reference in New Issue
Block a user