Test Failed
Push — main ( fc8ba5...9083af )
by Bingo
05:27
created

AbstractBatchJobHandler::saveConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Jabe\Engine\Impl\Batch;
4
5
use Jabe\Engine\Impl\Context\Context;
6
use Jabe\Engine\Impl\Interceptor\CommandContext;
7
use Jabe\Engine\Impl\JobExecutor\{
8
    JobDeclaration,
9
    JobHandlerConfigurationInterface
10
};
11
use Jabe\Engine\Impl\Json\JsonObjectConverter;
12
use Jabe\Engine\Impl\Persistence\Entity\{
13
    ByteArrayEntity,
14
    ByteArrayManager,
15
    JobEntity,
16
    JobManager,
17
    MessageEntity
18
};
19
use Jabe\Engine\Impl\Util\JsonUtil;
20
21
abstract class AbstractBatchJobHandler implements BatchJobHandlerInterface
22
{
23
    abstract public function getJobDeclaration(): JobDeclaration;
24
25
    public function createJobs(BatchEntity $batch): bool
26
    {
27
        $configuration = $this->readConfiguration($batch->getConfigurationBytes());
28
        $deploymentId = null;
29
30
        $idMappings = $configuration->getIdMappings();
31
        $deploymentAware = $idMappings != null && !empty($idMappings);
32
33
        $ids = $configuration->getIds();
34
35
        if ($deploymentAware) {
36
            $this->sanitizeMappings($idMappings, $ids);
37
            $mappingToProcess = $idMappings->get(0);
38
            $ids = $mappingToProcess->getIds($ids);
39
            $deploymentId = $mappingToProcess->getDeploymentId();
40
        }
41
42
        $batchJobsPerSeed = $batch->getBatchJobsPerSeed();
43
        $invocationsPerBatchJob = $batch->getInvocationsPerBatchJob();
44
45
        $numberOfItemsToProcess = min($invocationsPerBatchJob * $batchJobsPerSeed, count($ids));
46
47
        // view of process instances to process
48
        $processIds = array_slice($ids, 0, $numberOfItemsToProcess);
49
        $this->createJobEntities($batch, $configuration, $deploymentId, $processIds, $invocationsPerBatchJob);
50
        if ($deploymentAware) {
51
            if (empty($ids)) {
52
                // all ids of the deployment are handled
53
                $idMappings->remove(0);
54
            } else {
55
                $idMappings->get(0)->removeIds($numberOfItemsToProcess);
56
            }
57
        }
58
59
        // update batch configuration
60
        $batch->setConfigurationBytes($this->writeConfiguration($configuration));
61
62
        return $deploymentAware ? $idMappings->isEmpty() : empty($ids);
63
    }
64
65
    protected function sanitizeMappings(DeploymentMappings $idMappings, array $ids): void
66
    {
67
        // for mixed version SeedJob execution, there might be ids that have been processed
68
        // without updating the mappings, this is corrected here,
69
        // see https://jira.camunda.com/browse/CAM-11188
70
        $elementsToRemove = $idMappings->getOverallIdCount() - count($ids);
71
        if ($elementsToRemove > 0) {
72
            foreach ($idMappings as $key => $deploymentMapping) {
73
                if ($deploymentMapping->getCount() <= $elementsToRemove) {
74
                    $idMappings->remove($key);
75
                    $elementsToRemove -= $deploymentMapping->getCount();
76
                    if ($elementsToRemove == 0) {
77
                        break;
78
                    }
79
                } else {
80
                    $deploymentMapping->removeIds($elementsToRemove);
81
                    break;
82
                }
83
            }
84
        }
85
    }
86
87
    protected function createJobEntities(BatchEntity $batch, BatchConfiguration $configuration, string $deploymentId, array $processIds, int $invocationsPerBatchJob): void
88
    {
89
        if (empty($processIds)) {
90
            return;
91
        }
92
93
        $commandContext = Context::getCommandContext();
94
        $byteArrayManager = $commandContext->getByteArrayManager();
95
        $jobManager = $commandContext->getJobManager();
96
97
        $createdJobs = 0;
98
        while (!empty($processIds)) {
99
            $lastIdIndex = min($invocationsPerBatchJob, count($processIds));
100
            // view of process instances for this job
101
            $idsForJob = array_splice($processIds, 0, $lastIdIndex);
102
103
            $jobConfiguration = $this->createJobConfiguration($configuration, $idsForJob);
104
105
            $jobConfiguration->setBatchId($batch->getId());
106
107
            $configurationEntity = $this->saveConfiguration($byteArrayManager, $jobConfiguration);
108
109
            $job = $this->createBatchJob($batch, $configurationEntity);
110
            $job->setDeploymentId($deploymentId);
111
            $this->postProcessJob($configuration, $job, $jobConfiguration);
112
            $jobManager->insertAndHintJobExecutor($job);
113
114
            $idsForJob = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $idsForJob is dead and can be removed.
Loading history...
115
            $createdJobs += 1;
116
        }
117
118
        // update created jobs for batch
119
        $batch->setJobsCreated($batch->getJobsCreated() + $createdJobs);
120
    }
121
122
    abstract protected function createJobConfiguration(BatchConfiguration $configuration, array $processIdsForJob): BatchConfiguration;
123
124
    protected function postProcessJob(BatchConfiguration $configuration, JobEntity $job, BatchConfiguration $jobConfiguration): void
0 ignored issues
show
Unused Code introduced by
The parameter $job is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

124
    protected function postProcessJob(BatchConfiguration $configuration, /** @scrutinizer ignore-unused */ JobEntity $job, BatchConfiguration $jobConfiguration): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
125
    {
126
      // do nothing as default
127
    }
128
129
    protected function createBatchJob(BatchEntity $batch, ByteArrayEntity $configuration): JobEntity
130
    {
131
        $creationContext = new BatchJobContext($batch, $configuration);
132
        return $this->getJobDeclaration()->createJobInstance($creationContext);
133
    }
134
135
    public function deleteJobs(BatchEntity $batch): void
136
    {
137
        $jobs = Context::getCommandContext()
138
            ->getJobManager()
139
            ->findJobsByJobDefinitionId($batch->getBatchJobDefinitionId());
140
141
        foreach ($jobs as $job) {
142
            $job->delete();
143
        }
144
    }
145
146
    public function newConfiguration(string $canonicalString): JobHandlerConfigurationInterface
147
    {
148
        return new BatchJobConfiguration($canonicalString);
149
    }
150
151
    public function onDelete(JobHandlerConfigurationInterface $configuration, JobEntity $jobEntity): void
152
    {
153
        $byteArrayId = $configuration->getConfigurationByteArrayId();
0 ignored issues
show
Bug introduced by
The method getConfigurationByteArrayId() does not exist on Jabe\Engine\Impl\JobExec...rConfigurationInterface. It seems like you code against a sub-type of Jabe\Engine\Impl\JobExec...rConfigurationInterface such as Jabe\Engine\Impl\Batch\BatchJobConfiguration. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

153
        /** @scrutinizer ignore-call */ 
154
        $byteArrayId = $configuration->getConfigurationByteArrayId();
Loading history...
154
        if ($byteArrayId != null) {
155
            Context::getCommandContext()->getByteArrayManager()
156
                ->deleteByteArrayById($byteArrayId);
157
        }
158
    }
159
160
    protected function saveConfiguration(ByteArrayManager $byteArrayManager, BatchConfiguration $jobConfiguration): ByteArrayEntity
161
    {
162
        $configurationEntity = new ByteArrayEntity();
163
        $configurationEntity->setBytes($this->writeConfiguration($jobConfiguration));
164
        $byteArrayManager->insert($configurationEntity);
165
        return $configurationEntity;
166
    }
167
168
    public function writeConfiguration(BatchConfiguration $configuration): string
169
    {
170
        $jsonObject = $this->getJsonConverterInstance()->toJsonObject($configuration);
171
        return JsonUtil::asBytes($jsonObject);
0 ignored issues
show
Bug introduced by
It seems like $jsonObject can also be of type null; however, parameter $jsonObject of Jabe\Engine\Impl\Util\JsonUtil::asBytes() does only seem to accept stdClass, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

171
        return JsonUtil::asBytes(/** @scrutinizer ignore-type */ $jsonObject);
Loading history...
172
    }
173
174
    public function readConfiguration(string $serializedConfiguration): BatchConfiguration
175
    {
176
        return $this->getJsonConverterInstance()->toObject(JsonUtil::asObject($serializedConfiguration));
177
    }
178
179
    abstract protected function getJsonConverterInstance(): JsonObjectConverter;
180
}
181