Completed
Pull Request — master (#1103)
by Tim
07:25
created

AbstractStep::getAppEnvironment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
crap 2
1
<?php
2
3
/**
4
 * AppserverIo\Appserver\Provisioning\Steps\AbstractStep
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2015 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/appserver
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Appserver\Provisioning\Steps;
22
23
use AppserverIo\Appserver\Core\Environment;
24
use AppserverIo\Appserver\Core\Api\Node\StepNode;
25
use AppserverIo\Appserver\Core\Utilities\EnvironmentKeys;
26
use AppserverIo\Appserver\Provisioning\Utilities\ParamKeys;
27
use AppserverIo\Psr\Servlet\SessionUtils;
28
use AppserverIo\Psr\Application\ApplicationInterface;
29
use AppserverIo\Psr\ApplicationServer\ServiceInterface;
30
use AppserverIo\Psr\ApplicationServer\ContextInterface;
31
use AppserverIo\Psr\ApplicationServer\Configuration\DatasourceConfigurationInterface;
32
33
/**
34
 * Abstract base class for a step implementation.
35
 *
36
 * @author    Tim Wagner <[email protected]>
37
 * @copyright 2015 TechDivision GmbH <[email protected]>
38
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
39
 * @link      https://github.com/appserver-io/appserver
40
 * @link      http://www.appserver.io
41
 */
42
abstract class AbstractStep extends \Thread implements StepInterface
43
{
44
45
    /**
46
     * The maximum number of retries.
47
     *
48
     * @var integer
49
     */
50
    const MAX_RETRIES = 0;
51
52
    /**
53
     * The provisioning service.
54
     *
55
     * @var \AppserverIo\Appserver\Core\Api\ServiceInterface;
56
     */
57
    protected $service;
58
59
    /**
60
     * The step node with the configuration data for this step.
61
     *
62
     * @var \AppserverIo\Appserver\Core\Api\Node\StepNode
63
     */
64
    protected $stepNode;
65
66
    /**
67
     * The datasource node found in the provisioning configuration.
68
     *
69
     * @var \AppserverIo\Psr\ApplicationServer\Configuration\DatasourceConfigurationInterface
70
     */
71
    protected $datasourceNode;
72
73
    /**
74
     * The initial context.
75
     *
76
     * @var \AppserverIo\Psr\ApplicationServer\ContextInterface
77
     */
78
    protected $initialContext;
79
80
    /**
81
     * The absolute path to the appserver PHP executable.
82
     *
83
     * @var string
84
     */
85
    protected $phpExecutable;
86
87
    /**
88
     * The absolute path to the applications folder.
89
     *
90
     * @var string
91
     */
92
    protected $webappPath;
93
94
    /**
95
     * The application instance.
96
     *
97
     * @var \AppserverIo\Psr\Application\ApplicationInterface
98
     */
99
    protected $application;
100
101
    /**
102
     * Injects the provisioning service.
103
     *
104
     * @param \AppserverIo\Psr\ApplicationServer\ServiceInterface $service The provisioning service
105
     *
106
     * @return void
107
     */
108
    public function injectService(ServiceInterface $service)
109
    {
110
        $this->service = $service;
111
    }
112
113
    /**
114
     * Injects the step node with the configuration data for this step.
115
     *
116
     * @param \AppserverIo\Appserver\Core\Api\Node\StepNode $stepNode The step node data
117
     *
118
     * @return void
119
     */
120
    public function injectStepNode(StepNode $stepNode)
121
    {
122
        $this->stepNode = $stepNode;
123
    }
124
125
    /**
126
     * Injects the datasource node found in the provisioning configuration.
127
     *
128
     * @param \AppserverIo\Psr\ApplicationServer\Configuration\DatasourceConfigurationInterface $datasourceNode The datasource node data
129
     *
130
     * @return void
131
     */
132
    public function injectDatasourceNode(DatasourceConfigurationInterface $datasourceNode)
133
    {
134
        $this->datasourceNode = $datasourceNode;
135
    }
136
137
    /**
138
     * Injects the absolute path to the appservers PHP executable.
139
     *
140
     * @param string $phpExecutable The absolute path to the appservers PHP executable
141
     *
142
     * @return void
143
     */
144
    public function injectPhpExecutable($phpExecutable)
145
    {
146
        $this->phpExecutable = $phpExecutable;
147
    }
148
149
    /**
150
     * Injects the absolute path to the applications folder.
151
     *
152
     * @param string $webappPath The absolute path to applications folder
153
     *
154
     * @return void
155
     */
156
    public function injectWebappPath($webappPath)
157
    {
158
        $this->webappPath = $webappPath;
159
    }
160
161
    /**
162
     * Injects the initial context.
163
     *
164
     * @param \AppserverIo\Appserver\Core\InitialContext $initialContext The initial context instance
165
     *
166
     * @return void
167
     */
168
    public function injectInitialContext(ContextInterface $initialContext)
169
    {
170
        $this->initialContext = $initialContext;
171
    }
172
173
    /**
174
     * Injects the application instance.
175
     *
176
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
177
     *
178
     * @return void
179
     */
180
    public function injectApplication(ApplicationInterface $application)
181
    {
182
        $this->application = $application;
183
    }
184
185
    /**
186
     * Returns the provisioning service.
187
     *
188
     * @return \AppserverIo\Psr\ApplicationServer\ServiceInterface The provisioning service
189
     */
190
    protected function getService()
191
    {
192
        return $this->service;
193
    }
194
195
    /**
196
     * Returns the step node data.
197
     *
198
     * @return \AppserverIo\Appserver\Core\Api\Node\StepNode The step node data
199
     */
200
    protected function getStepNode()
201
    {
202
        return $this->stepNode;
203
    }
204
205
    /**
206
     * Returns the datasource node found in the provisioning configuration.
207
     *
208
     * @return \AppserverIo\Psr\ApplicationServer\Configuration\DatasourceConfigurationInterface The datasource node data
209
     */
210
    protected function getDatasourceNode()
211
    {
212
        return $this->datasourceNode;
213
    }
214
215
    /**
216
     * Returns the initial context instance.
217
     *
218
     * @return \AppserverIo\Psr\ApplicationServer\ContextInterface The initial context
219
     */
220
    protected function getInitialContext()
221
    {
222
        return $this->initialContext;
223
    }
224
225
    /**
226
     * Returns the absolute path to the appservers PHP executable.
227
     *
228
     * @return string The absolute path to the appservers PHP executable
229
     */
230
    protected function getPhpExecutable()
231
    {
232
        return $this->phpExecutable;
233
    }
234
235
    /**
236
     * Returns the absolute path to the applications folder.
237
     *
238
     * @return string The applications folder
239
     */
240
    protected function getWebappPath()
241
    {
242
        return $this->webappPath;
243
    }
244
245
    /**
246
     * Returns the application instance.
247
     *
248
     * @return \AppserverIo\Psr\Application\ApplicationInterface The application instance
249
     */
250
    protected function getApplication()
251
    {
252
        return $this->application;
253
    }
254
255
    /**
256
     * Will return the name of the application
257
     *
258
     * @return string
259
     */
260
    protected function getAppName()
261
    {
262
        return $this->getApplication()->getName();
263
    }
264
265
    /**
266
     * Will return the name of the application environment
267
     *
268
     * @return string
269
     */
270
    protected function getAppEnvironment()
271
    {
272
        return $this->getApplication()->getEnvironmentName();
273
    }
274
275
    /**
276
     * Return's the container instance the application is bound to.
277
     *
278
     * @return \AppserverIo\Psr\ApplicationServer\ContainerInterface The container instance
279
     */
280
    protected function getContainer()
281
    {
282
        return $this->getApplication()->getContainer();
283
    }
284
285
    /**
286
     * Return's the container configuration instance.
287
     *
288
     * @return \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface The container configuration
289
     */
290
    protected function getContainerNode()
291
    {
292
        return $this->getContainer()->getContainerNode();
293
    }
294
295
    /**
296
     * Return's the system properties.
297
     *
298
     * @return \AppserverIo\Properties\PropertiesInterface The system properties
299
     */
300
    protected function getSystemProperties()
301
    {
302
        return $this->getApplication()->getSystemProperties();
303
    }
304
305
    /**
306
     * Return's the maximum number of retries.
307
     *
308
     * @return integer The maximum number
309
     */
310
    protected function getMaxRetries()
311
    {
312
313
        // try to load the number of maximum retries from the step configuration
314
        $maxRetries = $this->getStepNode()->getParam(ParamKeys::MAX_RETRIES);
315
316
        // return the number of maximum retries
317
        return $maxRetries ? $maxRetries : AbstractStep::MAX_RETRIES;
318
    }
319
320
    /**
321
     * Logs the start of the provisioning.
322
     *
323
     * @return void
324
     */
325
    protected function logStart()
326
    {
327
        \info(
328
            sprintf(
329
                'Now start to execute provisioning step %s for application %s (env %s)',
330
                $this->getStepNode()->getType(),
331
                $this->getAppName(),
332
                $this->getAppEnvironment()
333
            )
334
        );
335
    }
336
337
    /**
338
     * Logs the retry of the provisioning.
339
     *
340
     * @param integer $retry         The retry number
341
     * @param string  $failureReason The reason the last try failed
342
     *
343
     * @return void
344
     */
345
    protected function logRetry($retry, $failureReason)
346
    {
347
        \info(
348
            sprintf(
349
                'Provisioning step %s of application %s (env %s) failed %d (of %d) times with message "%s"',
350
                $this->getStepNode()->getType(),
351
                $this->getAppName(),
352
                $this->getAppEnvironment(),
353
                $retry,
354
                AbstractStep::MAX_RETRIES,
355
                $failureReason
356
            )
357
        );
358
    }
359
360
    /**
361
     * Logs the success of the provisioning.
362
     *
363
     * @return void
364
     */
365
    protected function logSuccess()
366
    {
367
        \info(
368
            sprintf(
369
                'Successfully executed provisioning step %s of application %s (env %s)',
370
                $this->getStepNode()->getType(),
371
                $this->getAppName(),
372
                $this->getAppEnvironment()
373
            )
374
        );
375
    }
376
377
    /**
378
     * Return's the param with the passed name.
379
     *
380
     * @param string $name The name of the param to return
381
     *
382
     * @return mixed The param value
383
     */
384
    protected function getParam($name)
385
    {
386
        return $this->getStepNode()->getParam($name);
387
    }
388
389
    /**
390
     * Executes the steps functionality in a separate context.
391
     *
392
     * @return void
393
     */
394
    public function run()
395
    {
396
397
        // register the default autoloader
398
        require SERVER_AUTOLOADER;
399
400
        // register shutdown handler
401
        register_shutdown_function(array(&$this, "shutdown"));
402
403
        // synchronize the application instance and register the class loaders
404
        $application = $this->getApplication();
405
        $application->registerClassLoaders();
406
407
        // register the applications annotation registries
408
        $application->registerAnnotationRegistries();
409
410
        // add the application instance to the environment
411
        Environment::singleton()->setAttribute(EnvironmentKeys::APPLICATION, $application);
412
413
        // create s simulated request/session ID whereas session equals request ID
414
        Environment::singleton()->setAttribute(EnvironmentKeys::SESSION_ID, $sessionId = SessionUtils::generateRandomString());
415
        Environment::singleton()->setAttribute(EnvironmentKeys::REQUEST_ID, $sessionId);
416
417
        // initialize retry flag and counter
418
        $retry = true;
419
        $retryCount = 0;
420
421
        // log a message that provisioning starts
422
        $this->logStart();
423
424
        do {
425
            try {
426
                // run the actual provisioning
427
                $this->execute();
428
429
                // log a message that provisioning has been successfull
430
                $this->logSuccess();
431
432
                // don't retry, because step has been successful
433
                $retry = false;
434
            } catch (\Exception $e) {
435
                // raise the retry count
436
                $retryCount++;
437
                // query whether or not we've reached the maximum retry count
438
                if ($retryCount < $this->getMaxRetries()) {
439
                    // sleep for an increasing number of seconds
440
                    sleep($retryCount + 1);
441
                    // debug log the exception
442
                    $this->logRetry($retryCount, $e->getMessage());
443
                } else {
444
                    // log a message and stop retrying
445
                    \error($e);
446
                    $retry = false;
447
                }
448
            }
449
        } while ($retry);
450
    }
451
452
    /**
453
     * Shutdown function to log unexpected errors.
454
     *
455
     * @return void
456
     * @see http://php.net/register_shutdown_function
457
     */
458 View Code Duplication
    public function shutdown()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
459
    {
460
        // check if there was a fatal error caused shutdown
461
        if ($lastError = error_get_last()) {
462
            // initialize error type and message
463
            $type = 0;
464
            $message = '';
465
            // extract the last error values
466
            extract($lastError);
467
            // query whether we've a fatal/user error
468
            if ($type === E_ERROR || $type === E_USER_ERROR) {
469
                $this->getInitialContext()->getSystemLogger()->critical($message);
470
            }
471
        }
472
    }
473
}
474