Task created is null in Camunda using singleResult() method - camunda

I was creating a taskService in camunda with the following command, But am getting null task created. Any idea what could be the reason?
Task task = taskService.createTaskQuery()
.processInstanceBusinessKey(businessKey).initializeFormKeys().singleResult()
task evaluated to null.
businessKey is a valid non-empty string provided.

Either no task instance has been created / is active or the businessKey does not match.
Try less restrictive criteria and see if you get a result, for instance:
List<Task> taskList = taskService.createTaskQuery().active().list()
Then add the businessKey back and check if it matches. Did you correctly submit the businessKey when starting the instance?
If you only just started the process Instance and have access to the ID then you could also try to use the process instance id as filter criteria:
RuntimeService runtimeService = engine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("MyProcess");
TaskService taskService = engine.getTaskService();
List<Task> taskList = taskService.createTaskQuery()
.processInstanceId(processInstance.getId())
.list();
Task task = taskList.get(0);

Related

Using Spanner within Apache Beam Dataflow

I am trying to add a Spanner connection within an Apache Beam ParDo(DoFn). I need to lookup some rows as part of the ParDo. The dataflow creates a number of workers (usually 4 max) and I use the startBundle and finishBundle methods to open and close the spanner connections for the workers lifetime. Then within the processElement method I perform the lookup for each item passing the DatabaseClient and using a singleUseReadOnlyTransaction.
I should add this is running as a dataflow under GCP
Some code to illustrate this.
private static CustomDoFn<String, TransactionImport> processRow = new CustomDoFn<String, TransactionImport>(){
private static final long serialVersionUID = 1L;
private Spanner spanner = null;
private DatabaseClient dbClient = null;
#StartBundle
public void startBundle(StartBundleContext c){
TransactionFileOptions options = c.getPipelineOptions().as(TransactionFileOptions.class);
com.google.cloud.spanner.SpannerOptions spannerOptions = com.google.cloud.spanner.SpannerOptions.newBuilder().build();
spanner = spannerOptions.getService();
String spannerProjectID = options.getSpannerProjectId();
String spannerInstanceID = options.getSpannerInstanceId();
String spannerDatabaseID = options.getSpannerDatabaseId();
DatabaseId db = DatabaseId.of(spannerProjectID, spannerInstanceID, spannerDatabaseID);
dbClient = spanner.getDatabaseClient(db);
}
#FinishBundle
public void finishBundle(FinishBundleContext c){
spanner.close();
}
#ProcessElement
public void processElement(DoFn<String, TransactionImport>.ProcessContext c) throws Exception {
TransactionImport import = new TransactionImport();
Statement statement = Statement.newBuilder("SELECT * FROM Table1 WHERE Name= #Name")
.bind("Name").to( text)
.build();
ResultSet resultSet = dbClient.singleUseReadOnlyTransaction().executeQuery(statement);
// set some value on import dependant on retrieved value
c.output(import);
}
This always results in the dataflow not completing and when I check the log I see:
Processing stuck in step Process Rows for at least 05m00s without outputting or completing in state process
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
at com.google.common.util.concurrent.Uninterruptibles.takeUninterruptibly(Uninterruptibles.java:233)
at com.google.cloud.spanner.SessionPool$Waiter.take(SessionPool.java:411)
at com.google.cloud.spanner.SessionPool$Waiter.access$3300(SessionPool.java:399)
at com.google.cloud.spanner.SessionPool.getReadSession(SessionPool.java:754)
at com.google.cloud.spanner.DatabaseClientImpl.singleUseReadOnlyTransaction(DatabaseClientImpl.java:52)
at com.mycompany.pt.SpannerDataAccess.getBinDetails(SpannerDataAccess.java:197)
at com.mycompany.pt.transactionFiles.TransactionFileDataflow$1.processLine(TransactionFileDataflow.java:411)
at com.mycompany.pt.transactionFiles.TransactionFileDataflow$1.processElement(TransactionFileDataflow.java:336)
at com.mycompany.pt.transactionFiles.TransactionFileDataflow$1$DoFnInvoker.invokeProcessElement(Unknown Source)
`
Does anyone have any experience using Spanner like this within a ParDo?
I'm not a spanner expert, but maybe I can help:
You should use #Setup/#Teardown to connect & disconnect from spanner. #{Start,Finish}Bundle gets called multiple times over the lifetime of a worker. See here for more details: https://beam.apache.org/documentation/execution-model/#bundling-and-persistence
Does your processElement method ever emit an element using
c.output(...)? If not, beam will think your pipeline is stuck

Salesforce APEX Unit Test Error with REST Services / Error at SELECT of Case Object

I've succeeded to successfully construct a REST API using APEX language defined with an annotation: #RestResource.
I also wrote a matching Unit test procedure with #isTest annotation. The execution of the REST API triggered by a HTTP GET with two input parameters works well, while the Unit Test execution, returns a "null" value list resulting from the SOQL query shown below:
String mycase = inputs_case_number; // for ex. '00001026'
sObject[] sl2 = [SELECT Id, CaseNumber FROM Case WHERE CaseNumber = :mycase LIMIT 1];
The query returns:
VARIABLE_ASSIGNMENT [22]|sl2|[]|0x1ffefea6
I've also tried to execute it with a RunAs() method (see code below), using a dynamically created Salesforce test user, not anonymous, connected to a more powerful profile, but still receiving a "null" answer at the SOQL query. The new profile defines "View All" permission for Cases. Other SOQL queries to objects like: "User" and "UserRecordAccess" with very similar construction are working fine, both for REST APEX and Test APEX.
Is there a way to configure an access permission for Unit test (#isTest) to read the Case object and a few fields like: Id and CaseNumber. Is this error related to the "Tooling API" function and how can we fix this issue in the test procedure?
Code attachment: Unit Test Code
#isTest
private class MyRestResource1Test {
static testMethod void MyRestRequest() {
// generate temporary test user object and assign to running process
String uniqueUserName = 'standarduser' + DateTime.now().getTime() + '#testorg.com';
Profile p = [SELECT Id FROM Profile WHERE Name='StandardTestUser'];
User pu = new User(Alias='standt',Email='standarduser#testorg.com',LastName='testing',EmailEncodingKey='UTF-8',LanguageLocaleKey='en_US',LocaleSidKey='en_US',ProfileId=p.Id,TimeZoneSidKey='America/New_York',UserName=uniqueUserName);
System.RunAs(pu) {
RestRequest req = new RestRequest();
RestResponse res = new RestResponse();
req.requestURI = '/services/apexrest/sfcheckap/';
req.addParameter('useremail','testuserid#red.com');
req.addParameter('casenumber','00001026');
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response = res;
System.debug('Current User assigned is: ' + UserInfo.getUserName());
System.debug('Current Profile assigned is: ' + UserInfo.getProfileId());
Test.startTest();
Map<String, Boolean> resultMap = MyRestResource1.doGet();
Test.stopTest();
Boolean debugflag = resultMap.get('accessPermission');
String debugflagstr = String.valueOf(debugflag);
System.assert(debugflagstr.contains('true'));
}
}
}
Found a solution path by using: #isTest(SeeAllData=true)
See article: "Using the isTest(SeeAllData=true) Annotation"
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_seealldata_using.htm

Create NewRecord through Siebel Business Service eScript

I am trying to create a new record using BS server script.
Since the process is taking place inside the BS, the context of Parent is not present, hence I am unable to get Parent Row_Id which I need to explicitly stamp against the child record being created for visibility.
Initially I tried to pass the Parent Row_Id from applet as a profile, but this fails when there are no records in the child applet, ie this.BusComp().ParentBusComp().GetFieldValue returns "This operation is invalid when there are no records present" as the "this" context is unavailable.
Any suggestions?
I was able to achieve the desired with the below code
sId = TheApplication().ActiveBusObject().GetBusComp("Q").ParentBusComp().GetFieldValue("Id");
if(this.BusComp().CountRecords() > 0)
{
sA = TheApplication().ActiveBusObject().GetBusComp("Q").GetFieldValue("A");
sB = TheApplication().ActiveBusObject().GetBusComp("Q").GetFieldValue("B");
}
sEntity = TheApplication().ActiveBusObject().GetBusComp("Q").Name();
It is for these reasons that Siebel provides Pre-Default settings at the Business Component Field level. If you wish to do this entirely through scripting, you will have to find the Active context, you have to know which BC is the parent.
Lets say you know that the Parent BC has to be Account. So
ActiveBusObject().GetBusComp("Account").GetFieldValue("Id") will give you the row id of the currently selected Account BC record. But do make sure that this script fires only in this context. So check the ActiveViewName to check this.
if(TheApplication().GetProfileAttr("ActiveViewName")=="Custom View")
{
//put the scripting here.
}

Reset id sequence or update id on Grails Test

In Grails 1.3.7, I have a code that filters objects by ID and I need to test that
The domain class has a sequence
static mapping = {
id generator: 'sequence', params[sequence: 'seq_shipping_service']
}
In the test, the object is created several times and I need the identifier to be 11 in all the tests and even though, it deletes the whole database between every test, it doesn't reset the sequence. So I would get a superior ID
foo = createFoo()
foo.id = 11l
foo.save () //This gets error
My ideas are
1) Reset somehow the id sequence so it's everytime the same number between tests
2) Set somehow the id
I don't know if I make myself clear
Personally, if I need to do something like this I:
create an object mother to spawn all required objects (i.e. foo.id == 11)
use Groovy SQL to insert data into database. In your case:
public class BlahBlahTest extends Specification {
DataSource dataSource
def setup () {
new Sql(dataSource).exec ("insert into blablah (11, ...)")
}
...
Obviously you could do anything else there - for example recreate the sequence to start with 11.

Google Directory API - batch add members to a group

I am using the Google Admin SDK to create, update and delete mailing lists (aka groups).
Everything works fine so far and I can create a new group and add members to it. But: Every adding of a member takes about 1s so I was thinking of a batch request to add several users to a group at once.
In the Google Admin interface it is easy to add several users at once but I didn't find any way to implement this via the API.
Is there a way to do so or do I have to loop through every user?
This works but takes a lot of time if I have to do it for every single user:
$service = new Google_Service_Directory($this->getGoogleClient());
$user = new Google_Service_Directory_Member();
$user->setEmail('test#test.com');
$user->setRole('MEMBER');
$user->setType('USER');
$service->members->insert($group_id, $user);
finally I found a solution on my own: The Admin SDK comes with a Batch class :)
To get batch requests working these steps are necessary:
When initiating the Google Client add the following line to the code
$client->setUseBatch(true);
then you can initiate the batch object
$batch = new Google_Http_Batch($client);
a little modification on the code posted above brings me to this code
foreach($arr_users as $user)
{
$userdata = new Google_Service_Directory_Member();
$userdata->setEmail($user);
$userdata->setRole('MEMBER');
$userdata->setType('USER');
$batch->add($service->members->insert($temp_list_name, $userdata));
}
finally you have to execute the request which is done by this line:
$client->execute($batch);
that's all and it works perfectly
While using the method of Christian Lange I was getting this error -
Argument 1 passed to Google\Client::execute() must implement interface Psr\Http\Message\RequestInterface, instance of Google\Http\Batch given,
So I used this instead
$client->setUseBatch(true);
$service = new Google_Service_Directory($client);
$batch = $service->createBatch();
foreach ($emails as $email)
{
$user = new Google_Service_Directory_Member(array('email' => $email,
'kind' => 'member',
'role' => 'MEMBER',
'type' => 'USER'));
$list = $service->members->insert($key, $user);
$batch->add($list);
}
$resultsBatch = $batch->execute();