Salesforce: загрузка Apex Trigger через JavaJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Гость
 Salesforce: загрузка Apex Trigger через Java

Сообщение Гость »

Я хочу загрузить ApexTrigger в Salesforce через Java, поэтому, насколько мне известно, доступны следующие варианты:
  • Загрузить через REST >
  • Загрузка через SOAP
  • Загрузка через предопределенную/созданную библиотеку артефактов Maven
Для аутентификации у меня есть возможность использовать либо токен OAuth, возвращенный из Salesforce при входе в REST API, либо имя пользователя, пароль, токен безопасности, идентификатор клиента. , секрет клиента, а первый подход к повторному использованию токена REST API был бы моим любимым.
Ни одна из моих реальных попыток пока не сработала, и мой вопрос, очевидно, как заставить его работать или в чем моя ошибка.
Я пробовал следующее:
  • Загрузить через API метаданных createMetadata()

    developer.salesforce.com: Руководство разработчика API метаданных | Разработка метаданных на основе CRUD
[*]Загрузка через Tooling API POST /sobjects/SObjectName/< /code>
  • developer.salesforce.com API инструментов | Ресурсы REST

Подход API метаданных
Я начал с подхода API метаданных:
@Test
void testTriggerUploadMetadataApi() {
String username = "REDACTED";
String password = "REDACTED";
String securityToken = "REDACTED";
String url = "https://REDACTEDDOMAIN.my.salesforce.com/services/Soap";
String authPrefix = "/u";
String servicePrefix = "/m";
String version = "/60.0";

LoginResponse loginResponse = this.authController
.authLoginPost(new Login("REDACTED", "REDACTED").thirdPartyConfig(thirdPartyConfig))
.block();
assertNotNull(loginResponse);
// Session is here a wrapper for the actual REST API OAuth Token with additional metadata
Session session =
assertDoesNotThrow(() -> new ObjectMapper().readValue(loginResponse.getToken(), Session.class));

ConnectorConfig connectorConfig = new ConnectorConfig();
connectorConfig.setUsername(username);
connectorConfig.setPassword(password + securityToken);
connectorConfig.setAuthEndpoint("https://login.salesforce.com/service/Soap" + authPrefix + version);
connectorConfig.setServiceEndpoint(url + servicePrefix + version);
connectorConfig.setProxy("REDACTED", 8080);
Transport transport = new JdkHttpTransport(connectorConfig);
connectorConfig.setTransport(transport.getClass());

MetadataConnection metadataConnection = assertDoesNotThrow(() -> new MetadataConnection(connectorConfig));
metadataConnection.setSessionHeader(session.getBearerTokenString());

ApexTrigger apexTrigger = new ApexTrigger();
apexTrigger.setFullName("SomeTrigger");
apexTrigger.setStatus(ApexCodeUnitStatus.Active);
apexTrigger.setApiVersion(56.0);
apexTrigger.setContent(
"trigger SomeTrigger on Account(after insert, after update {}".getBytes(StandardCharsets.UTF_8));

assertDoesNotThrow(() -> metadataConnection.upsertMetadata(new Metadata[] {apexTrigger}));
}

В результате:
org.opentest4j.AssertionFailedError: Unexpected exception thrown: com.sforce.ws.SoapFaultException: INVALID_TYPE: This type of object is not available for this organization
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
at org.junit.jupiter.api.AssertDoesNotThrow.createAssertionFailedError(AssertDoesNotThrow.java:84)
at org.junit.jupiter.api.AssertDoesNotThrow.assertDoesNotThrow(AssertDoesNotThrow.java:75)
at org.junit.jupiter.api.AssertDoesNotThrow.assertDoesNotThrow(AssertDoesNotThrow.java:58)
at org.junit.jupiter.api.Assertions.assertDoesNotThrow(Assertions.java:3228)
at redacted.package.name.SFLoginTest.testTriggerUploadMetadataApi(SFLoginTest.java:139)

Затем я начал немного исследовать и нашел следующую ветку-новатора, где в комментариях Дэниел Баллинджер из Salesforce утверждает, что это, вероятно, невозможно, поскольку "Это тип метаданных не поддерживается вызовами create(), delete() и update().
Хотя это не является явным, это также относится к методу createMetadata(), для которого функция create() была устаревшей."
Он также утверждает, что «Вместо этого вы можете использовать метод развертывания API метаданных или API инструментов для создания класса Apex»., так что я продолжил исследование где я нашел эту ветку-новатора, где Сунад Расане заявляет, что вместо этого он использовал Tooling API со ссылкой на эту ветку обмена стеками, где приведен пример загрузки триггера через Tooling API уже присутствовал, поэтому я решил использовать Tooling API, поскольку он выглядел удобным в использовании:
Подход Tooling API
@Test
void testTriggerUploadToolingApi() {

Map thirdPartyConfig = getThirdPartyConfig();

LoginResponse loginResponse = this.authController
.authLoginPost(new Login("REDACTED", "REDACTED").thirdPartyConfig(thirdPartyConfig))
.block();
assertNotNull(loginResponse);
// Session is here a wrapper for the actual REST API OAuth Token with additional metadata
Session session =
assertDoesNotThrow(() -> new ObjectMapper().readValue(loginResponse.getToken(), Session.class));
String url = session.getBaseUrl() + "/services/data/" + session.getApiVersion() + "/sobjects/ApexTrigger";
System.out.println("Request URL: [" + url + "]");

Map apexTrigger = new LinkedHashMap();
apexTrigger.put("Name", "UploadTest_AccountTrigger");
apexTrigger.put("TableEnumOrId", "Account");
apexTrigger.put(
"Body",
assertDoesNotThrow(() -> Files.readString(
Path.of("src/test/resources/salesforce/apex/SimpleAccountTriggerExpected.txt"))));

String requestBody = assertDoesNotThrow(() -> new ObjectMapper().writeValueAsString(apexTrigger));
System.out.println("Request body: [" + requestBody + "]");

HttpClient httpClient = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("REDACTED", 8080)))
.connectTimeout(Duration.of(60, ChronoUnit.SECONDS))
.build();
HttpRequest uploadRequest = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.of(60, ChronoUnit.SECONDS))
.POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8))
.header("Authorization", "OAuth " + session.getBearerTokenString())
.header("Content-Type", "application/json")
.build();
HttpResponse response =
assertDoesNotThrow(() -> httpClient.send(uploadRequest, HttpResponse.BodyHandlers.ofString()));
System.out.println("Status Code: [" + response.statusCode()+ "]");
System.out.println("Body: [" + response.body() + "]");

assertTrue(String.valueOf(response.statusCode()).startsWith("2"));
}

В результате:
Expected :true
Actual :false


org.opentest4j.AssertionFailedError: expected: but was:
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)
at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)
at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:31)
at org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:183)
at redacted.package.nameSFLoginTest.testTriggerUploadToolingApi(SFLoginTest.java:83)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.micronaut.test.extensions.junit5.MicronautJunit5Extension$2.proceed(MicronautJunit5Extension.java:142)
at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:157)
at io.micronaut.test.extensions.AbstractMicronautExtension.interceptTest(AbstractMicronautExtension.java:114)
at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.interceptTestMethod(MicronautJunit5Extension.java:129)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Со следующим выводом на STDOUT:
Request URL: [https://REDACTEDDOMAIN.my.salesforce.co ... pexTrigger]
Request body: [{"Name":"UploadTest_AccountTrigger","TableEnumOrId":"Account","Body":"trigger Account_AccountWebhook on Account (after insert, after update) {}"}]
Status Code: [404]
Body: [[{"errorCode":"NOT_FOUND","message":"The requested resource does not exist"}]]


Подробнее здесь: https://stackoverflow.com/questions/781 ... r-via-java
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как подключить языковой сервер Apex (Salesforce) с помощью сырой Java?
    Anonymous » » в форуме JAVA
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Как подключить языковой сервер Apex (Salesforce) с помощью сырой Java?
    Anonymous » » в форуме JAVA
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Java Azure Function App Trigger Trigger - память не выпущена после вызова
    Anonymous » » в форуме JAVA
    0 Ответы
    25 Просмотры
    Последнее сообщение Anonymous
  • Как получить доступ к маркетинговому облаку Salesforce через Simple-Salesforce
    Anonymous » » в форуме Python
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Используйте WMS от GeoServer с листочкой в Apex Salesforce
    Anonymous » » в форуме Javascript
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»