Unable to deploy Platform Event using Ant Migration Tool - salesforce

I am having a problem uploading metadata to a Salesforce managed app build org, via the ant migration tool. The original problem was in quite a major app, but I have been able to cut it down to 2 files, which demonstrate the issue: a Platform Event and an Apex class (web service) that publishes it.
objects/CTIDeviceUpdateEvent__e:
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<deploymentStatus>Deployed</deploymentStatus>
<description>Event raised by AVS when the CTI user updates their outbound device.</description>
<eventType>StandardVolume</eventType>
<fields>
<fullName>NewCtiDevice__c</fullName>
<externalId>false</externalId>
<isFilteringDisabled>false</isFilteringDisabled>
<isNameField>false</isNameField>
<isSortingDisabled>false</isSortingDisabled>
<label>NewCtiDevice</label>
<length>64</length>
<required>true</required>
<type>Text</type>
<unique>false</unique>
</fields>
<fields>
<fullName>UserId__c</fullName>
<externalId>false</externalId>
<isFilteringDisabled>false</isFilteringDisabled>
<isNameField>false</isNameField>
<isSortingDisabled>false</isSortingDisabled>
<label>UserId</label>
<precision>18</precision>
<required>true</required>
<scale>0</scale>
<type>Number</type>
<unique>false</unique>
</fields>
<label>CTI Device Update Event</label>
<pluralLabel>CTI Device Update Events</pluralLabel>
</CustomObject>
classes CtiDeviceUpdateWebService.cls
global with sharing class CtiDeviceUpdateWebService {
webservice static void ctiDeviceUpdate(Integer natterboxUserId, String newCtiDeviceRaw) {
List<CTIDeviceUpdateEvent__e> evlist = new List<CTIDeviceUpdateEvent__e> { new CTIDeviceUpdateEvent__e(UserId__c = 1, NewCTIDevice__c = '2001') } ;
// Call method to publish events
List<Database.SaveResult> results = EventBus.publish(evlist);
// Inspect publishing result for each event
for (Database.SaveResult sr : results) {
if (sr.isSuccess()) {
System.debug('Successfully published event.');
} else {
for(Database.Error err : sr.getErrors()) {
System.debug('Error returned: ' +
err.getStatusCode() +
' - ' +
err.getMessage());
}
}
}
}
}
package.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>*</members>
<name>CustomObject</name>
</types>
<types>
<members>*</members>
<name>ApexClass</name>
</types>
<version>41.0</version>
</Package>
I get the following result from the metadata API when I deploy it:
[sf:deploy] Request for a deploy submitted successfully.
[sf:deploy] Request ID for the current deploy task: 0Af1n00001VmcmHCAR
[sf:deploy] Waiting for server to finish processing the request...
[sf:deploy] Request Status: InProgress
[sf:deploy] Request Status: Failed
BUILD FAILED
/Users/jim.page/Documents/salesforce_ant_43.0/nbavs/build.xml:31:
*********** DEPLOYMENT FAILED ***********
Request ID: 0Af1n00001VmcmHCAR
All Component Failures:
1. classes/CtiDeviceUpdateWebService.cls -- Error: Method does not exist or incorrect signature: void publish(List<CTIDeviceUpdateEvent__e>) from the type EventBus (line 12, column 54)
2. classes/CtiDeviceUpdateWebService.cls -- Error: Invalid type: CTIDeviceUpdateEvent__e (line 9, column 9)
*********** DEPLOYMENT FAILED ***********
I have tried different API versions, different settings in the event metadata of various kinds, using my managed package's namespace, and google and I are out of ideas.
Note - when I just deploy the platform event on its own, the deployment works and I can see it under Setup|Platform Events in the build org. But when the web service is added into the mix, the deployment fails. There is no problem accessing Custom Objects from the web service.
Note also that this code works fine in a dev org.

Ok - the moment I posted this question, one of my colleagues gave me the answer. The class metadata file had a version number that was pre-41.0 when platform events went into production.

Related

JPA/Wildfly/MsSql: GenericJDBCException: Unable to acquire JDBC Connection

currently my team and I are facing a strange problem. By now we have been spending 4 days searching for the solution.
We are developing a Java EE Web Application. We have been using Wildfly 14. Using Wildfly 14, there was no problem. Now we have upgraded Wildfly to Version 18 and afterwars to 19 and are now facing the following problem. As database we have an MS SQL.
The datasource looks like this:
<datasource jndi-name="java:/label" pool-name="Label">
<connection-url>jdbc:sqlserver://localhost:1433;DatabaseName=label</connection-url>
<driver>mssql-jdbc-8.2.2.jre8.jar</driver>
<security>
<user-name>label</user-name>
<password>label</password>
</security>
</datasource>
And the persistence.xml is the following:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="label-pu"
transaction-type="JTA">
<jta-data-source>java:/label</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.SQLServerDialect" />
</properties>
</persistence-unit>
We have a Bean in which we inject an EntityManager using the persistence-unit. When calling the bean's method we are getting an exception. The datasource is working. We checked that in the wildfly ui.
#Dependent
public class ConstructionService {
#PersistenceContext(unitName = "label-pu")
private EntityManager em;
public List<ConstructionRecordEntity> retrieveRecordForConstruction(int contructionId) {
String sqlSelectEmployeeId = "SELECT lfdnr, " + //
" erwkz1, " + //
" erwbe, " + //
" erwdat " + //
" FROM [label].[dbo].[aderw] where adnr = " + contructionId;//
return em//
.createNativeQuery(sqlSelectEmployeeId, ConstructionRecordEntity.class)//
.getResultList();
}
In the following you can see the stacktrace we are getting.
15:11:24,506 WARN [org.camunda.bpm.engine.rest.exception] (default task-1) ENGINE-REST-HTTP500 javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1515)
at org.hibernate.query.Query.getResultList(Query.java:132)
at de._._.ConstructionService.retrieveRecordForConstruction(ConstructionService.java:26)
...
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:109)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2082)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1990)
at org.hibernate.loader.Loader.doQuery(Loader.java:949)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:351)
at org.hibernate.loader.Loader.doList(Loader.java:2787)
at org.hibernate.loader.Loader.doList(Loader.java:2770)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2604)
at org.hibernate.loader.Loader.list(Loader.java:2599)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2243)
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1069)
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:170)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1506)
... 306 more
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener#c18c68f[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection#51667cf2 connection handles=0 lastReturned=1594905084472 lastValidated=1594904382991 lastCheckedOut=1594905084468 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool#66e3a014 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool#685b64a3[pool=Label] xaResource=LocalXAResourceImpl#671cf884[connectionListener=c18c68f connectionManager=bec01f1 warned=false currentXid=null productName=Microsoft SQL Server productVersion=15.00.2000 jndiName=java:/label] txSync=null]
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:159)
at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106)
... 325 more
Caused by: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener#c18c68f[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection#51667cf2 connection handles=0 lastReturned=1594905084472 lastValidated=1594904382991 lastCheckedOut=1594905084468 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool#66e3a014 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool#685b64a3[pool=Label] xaResource=LocalXAResourceImpl#671cf884[connectionListener=c18c68f connectionManager=bec01f1 warned=false currentXid=null productName=Microsoft SQL Server productVersion=15.00.2000 jndiName=java:/label] txSync=null]
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:792)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:151)
... 329 more
Caused by: javax.resource.ResourceException: IJ000461: Could not enlist in transaction on entering meta-aware object
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:571)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:977)
... 331 more
Caused by: javax.transaction.SystemException: Error enlisting resource in transaction=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffffc0a83801:34f7831:5f103dd7:8e1 status: ActionStatus.ABORT_ONLY >, owner=Local transaction context for provider JBoss JTA transaction provider)
at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.checkEnlisted(TxConnectionListener.java:957)
at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:394)
at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:564)
... 332 more
Caused by: java.lang.Throwable: Failed to enlist
at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.enlist(TxConnectionListener.java:1001)
at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379)
... 333 more
I apreciate any hint.
We found out, that this is related to Camunda, when we first thought is was a pure Java EE Problem.
Using the mentioned Bean in a Rest Service works perfectly. Only when we inject the Bean into a Camunda JavaDelegate there is a problem.
We could solve this by adding
<system-properties>
<property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
</system-properties>
to Wildfly Standalone.
It is working but we are getting a warning. Actually, this is necessary if you are using xa-datasource to have a transaction that surrounds multiple datasources. However, we do not have xa-datasource and we do not need a transaction that surrounds everything.
As far as we understand Camunda uses JTA to make the process jobs transaction safe. So when we are making a db query inside the JavaDelegate, there is a transaction inside a transaction. The first transaction is instantiated by Camunda the second one is instantiated by us by using JPA to query the database. Nevertheless, I do not understand. This scenario should be very common. So other people should have experienced this behavior, too? Or maybe it is related to the MS SQL Database?
The other thing that I do not understand is, that using JPA inside JavaDelegate worked with camunda 7.10 and in the latest version 7.13 it stopped working.
So, we found a workaround and we are not stuck anymore. Nonetheless, this workaround is not satisfying as we do not understand entirely what is going on underneath and we keep looking for an appropriate solution.
I was working with WildFly server long time ago so there is just my amateur thought:
There is something bad happened with transaction.
The issue point is connected with resource enlistement:
http://javadox.com/org.jboss.ironjacamar/ironjacamar-core-impl/1.2.7.Final/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.TransactionSynchronization.html#enlist()
According to the documentation, the database connection is also an "Transactional Resource". So, yes, we do not have an database connection for some reason.
May be someone close transaction for some reason? Try to check transaction status with injection of UserTransaction or with debugging of TxConnectionListener class (see the log)
If transaction is ok, then just debug from the point of error. Try to find the check that leads to an error. You can find the proper library to debug inside WildFly directory (with Far Manager, Double Commander and so on) and connect it to the IDE to be able to make a break point in the proper place.

How to log as jsonPayload to stackdriver from google app engine using logback?

My spring boot app uses logback to log messages in json format. The app is configured to use consolelogappender (stdout).When the logs appear in stackdriver, they appear as textPayload instead of jsonPayload. Is it possible to write message to jsonPayload field in stackdriver using logback? If not, what are my options to log in json format?
Based on this Github Link it seems the issue all log entries are seen as textpayload. It has been added as a Feature Request but we do not have an ETA on when it will be available.
I'm not entirely sure if an alternative exist as Logback seems to be giving extensive log information, but if you are able to use the Stackdriver Logging Client instead, you could format the entry in order to get your object as a JsonPayLoad, although you will have specify most of the log categories yourself which can be an extra amount of work.
The easy way to do this, is to implements the transformation of TextPayload(JSON Format) to JSONPayload on the LoggingEnhacer
Check this answer How to use Stackdriver Structured Logging in App Engine Flex Java environment
It is possible via google-cloud-logging-logback library.
However, please note following (from https://cloud.google.com/logging/docs/structured-logging):
Note: message is saved as textPayload if it is the only field remaining
after the Logging agent moves the other special-purpose fields and
detect_json wasn't enabled; otherwise message remains in jsonPayload.
detect_json is not applicable to managed logging environments like
Google Kubernetes Engine.
To add more data to json add an enhancer. Example:
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.google.cloud.logging.LogEntry;
import com.google.cloud.logging.Payload;
import com.google.cloud.logging.logback.LoggingEventEnhancer;
import java.util.HashMap;
public class EventEnhancer implements LoggingEventEnhancer {
#Override
public void enhanceLogEntry(
LogEntry.Builder logEntry,
ILoggingEvent e
) {
HashMap<String, Object> map = new HashMap<>();
map.put("thread", e.getThreadName());
map.put("context", e.getLoggerContextVO().getName());
map.put("logger", e.getLoggerName());
Payload.JsonPayload payload = logEntry.build().getPayload();
map.putAll(payload.getDataAsMap());
logEntry.setPayload(
Payload.JsonPayload.of(map)
);
}
}
Configuration:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration scan="true">
<appender name="CLOUD" class="com.google.cloud.logging.logback.LoggingAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<log>application.log</log>
<redirectToStdout>true</redirectToStdout>
<resourceType>gae_app</resourceType>
<loggingEventEnhancer>EventEnhancer</loggingEventEnhancer>
<flushLevel>INFO</flushLevel>
</appender>
<root level="INFO">
<appender-ref ref="CLOUD"/>
</root>
</configuration>

Salesforce Bulk API - "missing a mapping for the external id field" error

I'm starting a bulk API job and passing a spec file. Here is the job.txt file I'm using to create the job:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<operation>upsert</operation>
<object>Contact</object>
<externalIdFieldName>Unique_Email__c</externalIdFieldName>
<contentType>CSV</contentType>
</jobInfo>
Then, I'm posting a spec file as follows:
Salesforce Field,Csv Header,Value,Hint
Unique_Email__c,email1,,
Name,Full Name,,
And I get the error "Transformation specification is missing a mapping for the external id field" but that's very strange because the Unique_Email__c is actually there. What's going on?

What causes the InvalidEntity exception in the SFDC bulk api?

When creating a new bulk job through the API, I am getting an InvalidEntity as an exception code which isn't in SFDC's docs (pdf)
I'm making the following request
https://na13-api.salesforce.com/services/async/24.0/job
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<operation>query</operation>
<object>Campaign</object>
<concurrencyMode>Parallel</concurrencyMode>
<contentType>CSV</contentType>
</jobInfo>
And I get this response:
<?xml version="1.0" encoding="UTF-8"?><error
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<exceptionCode>InvalidEntity</exceptionCode>
<exceptionMessage>Entity 'Campaign' is not supported by the Bulk API.</exceptionMessage>
</error>
I've excluded the headers but I do have accept & content encoding specified as gzip and the content is gzipped when it is sent and received.
The requests work correctly for
Lead
Contact
Opportunity
Task
Event
OpportunityContactRole
Account
CampaignMember
Note
Profile
RecordType
User
I only get the exception shown above for:
Campaign
UserLicense
OpportunityStage
OpportunityHistory
LeadHistory
I'm only using the bulk api to download csv's out of salesforce and I've only tried the above entities because I don't need any others.
It has been a very long time, but I think you can get this exception if one of your foreign key relationships is incorrect.

Google App Engine time out?

In a Google App Engine app I used the following lines to read a page from a site :
String Url="http://...",line,Result="";
URL url=new URL(Url+"?r="+System.currentTimeMillis());
BufferedReader reader=new BufferedReader(new InputStreamReader(url.openStream()));
while ((line=reader.readLine())!=null) { Result+=line+"\n"; }
reader.close();
But I got the following error :
Uncaught exception from servlet
com.google.apphosting.api.DeadlineExceededException: This request (f5e2889605d27d42) started at 2011/09/07 03:20:41.458 UTC and was still executing at 2011/09/07 03:21:30.888 UTC.
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1326)
at com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:276)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:82)
at com.google.appengine.tools.development.TimedFuture.get(TimedFuture.java:55)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:69)
at com.google.apphosting.runtime.ApiProxyImpl.doSyncCall(ApiProxyImpl.java:177)
at com.google.apphosting.runtime.ApiProxyImpl.access$000(ApiProxyImpl.java:56)
at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:150)
at com.google.apphosting.runtime.ApiProxyImpl$1.run(ApiProxyImpl.java:148)
at java.security.AccessController.doPrivileged(Native Method)
Seems it took longer than it would like to wait, what can I do if that site is slow ?
A DeadlineExceededException is thrown when your code, handling the request to your web application takes over 30 seconds to process. Presumably your code is taking a while to process because of the length of time it had to wait to receive data from some other site.
You can create a task on a task queue to fetch and process that data, and change your web request/response flow to reply with progress on your task.
If your code is running inside a request handler, then by default there is an App-Engine-enforced 60 second deadline. You can't change it. See the "Deadlines" row / "automatic scaling" column of the chart on this page under "Scaling types":
https://developers.google.com/appengine/docs/java/modules/
However, this code will be able to run for some hours if you change your module to use "manual scaling" and a "B1"-"B4" instance. Example:
default/src/main/webapp/WEB-INF/appengine-web.xml:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>myapp</application>
<module>default</module>
<version>1</version>
<threadsafe>true</threadsafe>
<instance-class>B1</instance-class>
<manual-scaling>
<instances>1</instances>
</manual-scaling>
</appengine-web-app>
On this type of instance, your requests will typically not time out for hours. (The documentation claims that the deadline is "indefinite".)

Resources