Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid using Camel Salesforce DTO types as the return type or method parameters in integration tests #3291

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import org.apache.camel.component.salesforce.api.dto.AbstractDTOBase;
import org.apache.camel.component.salesforce.api.dto.PlatformEvent;
import org.apache.camel.component.salesforce.internal.dto.PushTopic;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;

class SalesforceProcessor {

private static final String SALESFORCE_DTO_PACKAGE = "org.apache.camel.component.salesforce.api.dto";
private static final String SALESFORCE_INTERNAL_DTO_PACKAGE = "org.apache.camel.component.salesforce.internal.dto";
private static final String FEATURE = "camel-salesforce";

@BuildStep
Expand All @@ -46,29 +46,27 @@ ExtensionSslNativeSupportBuildItem activateSslNativeSupport() {
void registerForReflection(CombinedIndexBuildItem combinedIndex, BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
IndexView index = combinedIndex.getIndex();

// Register everything extending AbstractDTOBase for reflection
DotName dtoBaseName = DotName.createSimple(AbstractDTOBase.class.getName());
String[] dtoClasses = index.getAllKnownSubclasses(dtoBaseName)
// NOTE: DTO classes are registered for reflection with fields and methods due to:
// https://issues.apache.org/jira/browse/CAMEL-16860

// Register Camel Salesforce DTO classes for reflection
String[] camelSalesforceDtoClasses = index.getKnownClasses()
.stream()
.map(classInfo -> classInfo.name().toString())
.filter(className -> className.startsWith(SALESFORCE_DTO_PACKAGE)
|| className.startsWith(SALESFORCE_INTERNAL_DTO_PACKAGE))
.toArray(String[]::new);

reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, dtoClasses));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, camelSalesforceDtoClasses));

// Register internal DTO classes for reflection
String[] internalDtoClasses = index.getKnownClasses()
// Register user generated DTOs for reflection
DotName dtoBaseName = DotName.createSimple(AbstractDTOBase.class.getName());
String[] userDtoClasses = index.getAllKnownSubclasses(dtoBaseName)
.stream()
.map(classInfo -> classInfo.name().toString())
.filter(className -> className.startsWith("org.apache.camel.component.salesforce.internal.dto"))
// it is registred below with fields accessible
.filter(className -> className != PushTopic.class.getName())
.filter(className -> !className.startsWith("org.apache.camel.component.salesforce"))
.toArray(String[]::new);

reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, internalDtoClasses));

// enabling the search for private fields : related to issue https://issues.apache.org/jira/browse/CAMEL-16860
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, PushTopic.class));
// enabling custom fields : related to issue https://github.com/apache/camel-quarkus/issues/3067
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, PlatformEvent.class));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, userDtoClasses));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
package org.apache.camel.quarkus.component.salesforce;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.Consumes;
Expand All @@ -41,9 +45,11 @@
import org.apache.camel.Exchange;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.component.salesforce.SalesforceEndpointConfig;
import org.apache.camel.component.salesforce.api.dto.Attributes;
import org.apache.camel.component.salesforce.api.dto.CreateSObjectResult;
import org.apache.camel.component.salesforce.api.dto.GlobalObjects;
import org.apache.camel.component.salesforce.api.dto.Limits;
import org.apache.camel.component.salesforce.api.dto.RecentItem;
import org.apache.camel.component.salesforce.api.dto.RestResources;
import org.apache.camel.component.salesforce.api.dto.SObjectBasicInfo;
import org.apache.camel.component.salesforce.api.dto.SObjectDescription;
Expand Down Expand Up @@ -82,28 +88,18 @@ public String getDocument(@PathParam("id") String id) {
.request(String.class);
}

@Path("/account")
@Path("/account/query/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Account getAccount() {
public JsonObject getAccountByQueryRecords(@PathParam("id") String accountId) {
String query = QueryHelper.queryToFetchFilteredFieldsOf(new Account(),
sObjectField -> sObjectField.getName().equals("Id") || sObjectField.getName().equals("AccountNumber"));
QueryRecordsAccount request = template
.toF("salesforce:query?sObjectQuery=SELECT Id,AccountNumber from Account LIMIT 1&sObjectClass=%s",
.toF("salesforce:query?sObjectQuery=%s&sObjectClass=%s",
query + " WHERE Id = '" + accountId + "'",
QueryRecordsAccount.class.getName())
.request(QueryRecordsAccount.class);
return request.getRecords().get(0);
}

@Path("/account/query")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Account getAccountByQueryHelper() {
String generatedQuery = QueryHelper.queryToFetchAllFieldsOf(new Account());
QueryRecordsAccount request = template
.toF("salesforce:query?sObjectQuery=%s LIMIT 1&sObjectClass=%s",
generatedQuery,
QueryRecordsAccount.class.getName())
.request(QueryRecordsAccount.class);
return request.getRecords().get(0);
return accountToJsonObject(request.getRecords().get(0));
}

@Path("/account")
Expand All @@ -113,6 +109,7 @@ public Account getAccountByQueryHelper() {
public String createAccount(String accountName) {
final Account account = new Account();
account.setName(accountName);
account.setAccountNumber(UUID.randomUUID().toString());

CreateSObjectResult result = template.to("salesforce:createSObject?sObjectName=Account")
.withBody(account)
Expand All @@ -137,12 +134,12 @@ public Response deleteAccount(@PathParam("id") String accountId) {
@Path("/account/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Account getAccountById(@PathParam("id") String accountId) {
public JsonObject getAccountById(@PathParam("id") String accountId) {
Account account = template
.to("salesforce:getSObjectWithId?sObjectName=Account&sObjectIdName=Id&sObjectClass=" + Account.class.getName())
.withBody(accountId)
.request(Account.class);
return account;
return accountToJsonObject(account);
}

@Path("/bulk")
Expand Down Expand Up @@ -184,71 +181,71 @@ public Response modifyCdcConsumerState(@PathParam("action") String action) throw
@Path("/cdc")
@GET
@Produces(MediaType.APPLICATION_JSON)
@SuppressWarnings("unchecked")
public Map<String, Object> getCdcEvents() {
Map map = consumerTemplate.receiveBody("seda:events", 10000, Map.class);
return map;
}

private JobInfo createJobInfo() {
JobInfo jobInfo = new JobInfo();
jobInfo.setObject(Account.class.getSimpleName());
jobInfo.setContentType(ContentType.CSV);
return jobInfo;
}

private JsonObject jobInfoToJsonObject(JobInfo jobInfo) {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
objectBuilder.add("id", jobInfo.getId());
objectBuilder.add("state", jobInfo.getState().value().toUpperCase(Locale.US));
return objectBuilder.build();
return consumerTemplate.receiveBody("seda:events", 10000, Map.class);
}

@Path("sobjects/force-limit")
@GET
@Produces(MediaType.APPLICATION_JSON)
public GlobalObjectsAndHeaders getSObjectsWithForceLimitInfo() {
public String getSObjectsWithForceLimitInfo() {
// Testing producer with headers
Exchange exchange = template.to("salesforce:getGlobalObjects")
.withHeader("Sforce-Limit-Info", Collections.singletonList("api-usage")).send();
GlobalObjectsAndHeaders objectsAndHeaders = new GlobalObjectsAndHeaders(
exchange.getMessage().getBody(GlobalObjects.class))
.withHeader("Sforce-Limit-Info", exchange.getMessage().getHeader("Sforce-Limit-Info", String.class));
return objectsAndHeaders;
return objectsAndHeaders.getHeader("Sforce-Limit-Info");
}

@Path("versions")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Version> getListVersions() {
return template.to("salesforce:getVersions").request(List.class);
@SuppressWarnings("unchecked")
public List<String> getListVersions() {
List<Version> versions = template.to("salesforce:getVersions").request(List.class);
return versions.stream()
.map(Version::getVersion)
.collect(Collectors.toList());
}

@Path("resources")
@GET
@Produces(MediaType.APPLICATION_JSON)
public RestResources getListResources() {
return template.to("salesforce:getResources").request(RestResources.class);
public String getListResources() {
RestResources restResources = template.to("salesforce:getResources").request(RestResources.class);
return restResources.getSobjects();
}

@Path("basic-info/account")
@GET
public SObjectBasicInfo getAccountBasicInfo() {
return template.to("salesforce:getBasicInfo?sObjectName=Account")
.request(SObjectBasicInfo.class);
public JsonObject getAccountBasicInfo() {
SObjectBasicInfo basicInfo = template.to("salesforce:getBasicInfo?sObjectName=Account").request(SObjectBasicInfo.class);
return basicInfoToJsonObject(basicInfo);
}

@Path("describe/account")
@GET
public SObjectDescription getAccountDescription() {
return template.to("salesforce:getDescription?sObjectName=Account")
public String getAccountDescription() {
SObjectDescription sObjectDescription = template.to("salesforce:getDescription?sObjectName=Account")
.request(SObjectDescription.class);
return sObjectDescription.getName();
}

@Path("limits")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Limits getLimits() {
return template.to("salesforce:limits").request(Limits.class);
public Map<String, Integer> getLimits() {
Limits limits = template.to("salesforce:limits").request(Limits.class);

Map<String, Integer> limitInfo = new HashMap<>();
for (Limits.Operation operation : Limits.Operation.values()) {
Limits.Usage usage = limits.forOperation(operation.name());
limitInfo.put(operation.name(), usage.getRemaining());
}

return limitInfo;
}

@Path("streaming")
Expand Down Expand Up @@ -296,4 +293,48 @@ public String getTopicId() {
public String getPlatformEvent() {
return consumerTemplate.receiveBody("salesforce:event/TestEvent__e?rawPayload=true", 10000, String.class);
}

private JsonObject accountToJsonObject(Account account) {
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("Id", account.getId());
builder.add("AccountNumber", account.getAccountNumber());
return builder.build();
}

private JobInfo createJobInfo() {
JobInfo jobInfo = new JobInfo();
jobInfo.setObject(Account.class.getSimpleName());
jobInfo.setContentType(ContentType.CSV);
return jobInfo;
}

private JsonObject jobInfoToJsonObject(JobInfo jobInfo) {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
objectBuilder.add("id", jobInfo.getId());
objectBuilder.add("state", jobInfo.getState().value().toUpperCase(Locale.US));
return objectBuilder.build();
}

private JsonObject basicInfoToJsonObject(SObjectBasicInfo basicInfo) {
JsonObjectBuilder builder = Json.createObjectBuilder();

List<RecentItem> recentItems = basicInfo.getRecentItems();
JsonArrayBuilder recentItemsArrayBuilder = Json.createArrayBuilder();
for (RecentItem recentItem : recentItems) {
JsonObjectBuilder recentItemBuilder = Json.createObjectBuilder();
recentItemBuilder.add("Id", recentItem.getId());
recentItemBuilder.add("Name", recentItem.getName());

Attributes attributes = recentItem.getAttributes();
JsonObjectBuilder attributesObjectBuilder = Json.createObjectBuilder();
attributesObjectBuilder.add("url", attributes.getUrl());
recentItemBuilder.add("attributes", attributesObjectBuilder);

recentItemsArrayBuilder.add(recentItemBuilder);
}

builder.add("recentItems", recentItemsArrayBuilder);

return builder.build();
}
}