Skip to content

Commit

Permalink
FINERACT-2169: SMS API refactoring and clean up;
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorpavlenko committed Feb 20, 2025
1 parent 81ed026 commit 87e6f6d
Show file tree
Hide file tree
Showing 34 changed files with 545 additions and 703 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
*/
public class DateParam {

public static final String FROM_DATE_PARAM = "fromDate";
public static final String TO_DATE_PARAM = "toDate";

private final String dateAsString;

public DateParam(final String dateStr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@ public Map<String, Object> getMessageGateWayRequestURI(final String apiEndPoint,
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add(SmsCampaignConstants.FINERACT_PLATFORM_TENANT_ID, tenant.getTenantIdentifier());
headers.add(SmsCampaignConstants.FINERACT_TENANT_APP_KEY, messageGatewayConfigurationData.getTenantAppKey());
headers.add(SmsCampaignConstants.FINERACT_TENANT_APP_KEY, messageGatewayConfigurationData.tenantAppKey());
StringBuilder pathBuilder = new StringBuilder();
String endPoint = messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals("/")
? ""
: messageGatewayConfigurationData.getEndPoint();
pathBuilder = messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals("/")
String endPoint = messageGatewayConfigurationData.endPoint() == null || messageGatewayConfigurationData.endPoint().equals("/") ? ""
: messageGatewayConfigurationData.endPoint();
pathBuilder = messageGatewayConfigurationData.endPoint() == null || messageGatewayConfigurationData.endPoint().equals("/")
? pathBuilder.append("{apiEndPoint}")
: pathBuilder.append("{endPoint}/{apiEndPoint}");
// pathBuilder.append("{endPoint}/{apiEndPoint}") ;
UriBuilder builder = UriBuilder.fromPath(pathBuilder.toString()).host(messageGatewayConfigurationData.getHostName()).scheme("http")
.port(messageGatewayConfigurationData.getPortNumber());
URI uri = messageGatewayConfigurationData.getEndPoint() == null || messageGatewayConfigurationData.getEndPoint().equals("/")
UriBuilder builder = UriBuilder.fromPath(pathBuilder.toString()).host(messageGatewayConfigurationData.hostName()).scheme("http")
.port(messageGatewayConfigurationData.portNumber());
URI uri = messageGatewayConfigurationData.endPoint() == null || messageGatewayConfigurationData.endPoint().equals("/")
? builder.build(apiEndPoint)
: builder.build(endPoint, apiEndPoint);
HttpEntity<?> entity = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*/
package org.apache.fineract.infrastructure.campaigns.sms.api;

import static org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignHandlerDto.ACTIVATE_COMMAND;
import static org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignHandlerDto.CLOSE_COMMAND;
import static org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignHandlerDto.REACTIVATE_COMMAND;

import com.google.gson.JsonElement;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand All @@ -34,10 +38,7 @@
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import java.util.HashSet;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.commands.domain.CommandWrapper;
Expand All @@ -47,18 +48,19 @@
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
import org.apache.fineract.infrastructure.campaigns.sms.data.CampaignPreviewData;
import org.apache.fineract.infrastructure.campaigns.sms.data.SmsCampaignData;
import org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignCreationDto;
import org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignHandlerDto;
import org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignPreviewDto;
import org.apache.fineract.infrastructure.campaigns.sms.data.dto.SmsCampaignUpdateDto;
import org.apache.fineract.infrastructure.campaigns.sms.service.SmsCampaignReadPlatformService;
import org.apache.fineract.infrastructure.campaigns.sms.service.SmsCampaignWritePlatformService;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.api.JsonQuery;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.infrastructure.security.service.SqlValidator;
import org.springframework.stereotype.Component;

@Path("/v1/smscampaigns")
Expand All @@ -68,14 +70,11 @@ public class SmsCampaignApiResource {

private final PlatformSecurityContext platformSecurityContext;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final DefaultToApiJsonSerializer<SmsCampaignData> toApiJsonSerializer;
private final SmsCampaignReadPlatformService smsCampaignReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final FromJsonHelper fromJsonHelper;
private final DefaultToApiJsonSerializer<CampaignPreviewData> previewCampaignMessageDefaultToApiJsonSerializer;
private final SmsCampaignWritePlatformService smsCampaignWritePlatformService;
private final PlatformSecurityContext context;
private final SqlValidator sqlValidator;
private final DefaultToApiJsonSerializer<String> toApiJsonSerializer;

private static final String RESOURCE_NAME_FOR_PERMISSIONS = "SMS_CAMPAIGN";

Expand All @@ -92,11 +91,9 @@ public class SmsCampaignApiResource {
smscampaigns/template""")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SmsCampaignData.class)))
public String template(@Context final UriInfo uriInfo) {
public SmsCampaignData template() {
platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
final SmsCampaignData smsCampaignData = smsCampaignReadPlatformService.retrieveTemplate(CampaignType.SMS.name());
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return toApiJsonSerializer.serialize(settings, smsCampaignData);
return smsCampaignReadPlatformService.retrieveTemplate(CampaignType.SMS.name());
}

@POST
Expand All @@ -110,11 +107,11 @@ public String template(@Context final UriInfo uriInfo) {
paramValue in json format""")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = CommandWrapper.class)))
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CommandProcessingResult.class)))
public String createCampaign(@Parameter(hidden = true) final String apiRequestBodyAsJson) {
public CommandProcessingResult createCampaign(@Parameter(hidden = true) final SmsCampaignCreationDto smsCampaignCreationDto) {
platformSecurityContext.authenticatedUser();
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSmsCampaign().withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
return toApiJsonSerializer.serialize(result);
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSmsCampaign()
.withJson(toApiJsonSerializer.serialize(smsCampaignCreationDto)).build();
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}

@GET
Expand All @@ -126,12 +123,9 @@ public String createCampaign(@Parameter(hidden = true) final String apiRequestBo
smscampaigns/1
""")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SmsCampaignData.class)))
public String retrieveCampaign(@PathParam("resourceId") final Long resourceId, @Context final UriInfo uriInfo) {
public SmsCampaignData retrieveCampaign(@PathParam("resourceId") final Long resourceId) {
platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
SmsCampaignData smsCampaignData = smsCampaignReadPlatformService.retrieveOne(resourceId);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return toApiJsonSerializer.serialize(settings, smsCampaignData);

return smsCampaignReadPlatformService.retrieveOne(resourceId);
}

@GET
Expand All @@ -141,16 +135,12 @@ public String retrieveCampaign(@PathParam("resourceId") final Long resourceId, @
smscampaigns""")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SmsCampaignData.class)))
public String retrieveAllEmails(@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder, @Context final UriInfo uriInfo) {
public Page<SmsCampaignData> retrieveAllEmails(@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
platformSecurityContext.authenticatedUser().validateHasReadPermission(SmsCampaignConstants.RESOURCE_NAME);
sqlValidator.validate(orderBy);
sqlValidator.validate(sortOrder);
final SearchParameters searchParameters = SearchParameters.builder().limit(limit).offset(offset).orderBy(orderBy)
.sortOrder(sortOrder).build();
Page<SmsCampaignData> smsCampaignDataCollection = smsCampaignReadPlatformService.retrieveAll(searchParameters);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return toApiJsonSerializer.serialize(settings, smsCampaignDataCollection);
return smsCampaignReadPlatformService.retrieveAll(searchParameters);
}

@PUT
Expand All @@ -160,12 +150,11 @@ public String retrieveAllEmails(@QueryParam("offset") final Integer offset, @Que
@Operation(summary = "Update a Campaign")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = CommandWrapper.class)))
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CommandProcessingResult.class)))
public String updateCampaign(@PathParam("campaignId") final Long campaignId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSmsCampaign(campaignId).withJson(apiRequestBodyAsJson)
.build();
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
return toApiJsonSerializer.serialize(result);
public CommandProcessingResult updateCampaign(@PathParam("campaignId") final Long campaignId,
@Parameter(hidden = true) final SmsCampaignUpdateDto smsCampaignUpdateDto) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSmsCampaign(campaignId)
.withJson(toApiJsonSerializer.serialize(smsCampaignUpdateDto)).build();
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}

@POST
Expand All @@ -174,51 +163,43 @@ public String updateCampaign(@PathParam("campaignId") final Long campaignId,
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "SMS Campaign", description = "Activates | Deactivates | Reactivates")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CommandProcessingResult.class)))
public String handleCommands(@PathParam("campaignId") final Long campaignId, @QueryParam("command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
CommandWrapper commandRequest;
if (is(commandParam, "activate")) {
commandRequest = builder.activateSmsCampaign(campaignId).build();
result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "close")) {
commandRequest = builder.closeSmsCampaign(campaignId).build();
result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "reactivate")) {
commandRequest = builder.reactivateSmsCampaign(campaignId).build();
result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
return toApiJsonSerializer.serialize(result);
public CommandProcessingResult handleCommands(@PathParam("campaignId") final Long campaignId,
@QueryParam("command") final String commandParam, @Parameter(hidden = true) SmsCampaignHandlerDto campaignHandlerDto) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(toApiJsonSerializer.serialize(campaignHandlerDto));
return getCommandProcessingResult(commandParam, builder, campaignId);
}

@POST
@Path("preview")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String preview(final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
public CampaignPreviewData preview(SmsCampaignPreviewDto previewDto) {
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);

CampaignPreviewData campaignMessage;
final JsonElement parsedQuery = fromJsonHelper.parse(apiRequestBodyAsJson);
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, fromJsonHelper);
campaignMessage = smsCampaignWritePlatformService.previewMessage(query);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return previewCampaignMessageDefaultToApiJsonSerializer.serialize(settings, campaignMessage, new HashSet<>());

final String strPreviewDtoJson = toApiJsonSerializer.serialize(previewDto);
final JsonElement parsedQuery = fromJsonHelper.parse(strPreviewDtoJson);
final JsonQuery query = JsonQuery.from(strPreviewDtoJson, parsedQuery, fromJsonHelper);
return smsCampaignWritePlatformService.previewMessage(query);
}

@DELETE
@Path("{campaignId}")
@Operation(summary = "Delete a SMS Campaign", description = "Note: Only closed SMS Campaigns can be deleted")
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CommandProcessingResult.class)))
public String delete(@PathParam("campaignId") final Long campaignId) {
public CommandProcessingResult delete(@PathParam("campaignId") final Long campaignId) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSmsCampaign(campaignId).build();
final CommandProcessingResult result = commandsSourceWritePlatformService.logCommandSource(commandRequest);
return toApiJsonSerializer.serialize(result);
return commandsSourceWritePlatformService.logCommandSource(commandRequest);
}

private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
private CommandProcessingResult getCommandProcessingResult(String commandParam, CommandWrapperBuilder builder, Long campaignId) {
if (StringUtils.isBlank(commandParam)) {
return null;
}
return switch (commandParam.trim().toLowerCase()) {
case ACTIVATE_COMMAND -> commandsSourceWritePlatformService.logCommandSource(builder.activateSmsCampaign(campaignId).build());
case CLOSE_COMMAND -> commandsSourceWritePlatformService.logCommandSource(builder.closeSmsCampaign(campaignId).build());
case REACTIVATE_COMMAND ->
commandsSourceWritePlatformService.logCommandSource(builder.reactivateSmsCampaign(campaignId).build());
default -> null;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
*/
package org.apache.fineract.infrastructure.campaigns.sms.constants;

import lombok.Getter;

@Getter
public enum SmsCampaignStatus {

INVALID(-1, "smsCampaignStatus.invalid"), //
Expand All @@ -34,38 +37,11 @@ public enum SmsCampaignStatus {
}

public static SmsCampaignStatus fromInt(final Integer statusValue) {
switch (statusValue) {
case 100:
return PENDING;
case 300:
return ACTIVE;
case 600:
return CLOSED;
default:
return INVALID;
}
}

public Integer getValue() {
return value;
}

public String getCode() {
return code;
}

// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isActive() {
return this.equals(ACTIVE);
}

// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isPending() {
return this.equals(PENDING);
}

// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClosed() {
return this.equals(CLOSED);
return switch (statusValue) {
case 100 -> PENDING;
case 300 -> ACTIVE;
case 600 -> CLOSED;
default -> INVALID;
};
}
}
Loading

0 comments on commit 87e6f6d

Please sign in to comment.