StandardProvisioner   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 50
dl 0
loc 165
ccs 0
cts 66
cp 0
rs 10
c 0
b 0
f 0
wmc 13

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getAbsolutPathToPhpExecutable() 0 14 2
B provision() 0 69 6
A executeProvision() 0 33 5
1
<?php
2
3
/**
4
 * AppserverIo\Provisioning\StandardProvisioner
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 2018 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/provisioning
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Provisioning;
22
23
use Doctrine\Common\Annotations\AnnotationRegistry;
24
use AppserverIo\Psr\Application\ApplicationInterface;
25
use AppserverIo\Configuration\ConfigurationException;
26
use AppserverIo\Provisioning\Api\Node\ProvisionNode;
27
use AppserverIo\Provisioning\Configuration\ProvisionConfigurationInterface;
28
29
/**
30
 * Standard provisioning functionality.
31
 *
32
 * @author    Tim Wagner <[email protected]>
33
 * @copyright 2018 TechDivision GmbH <[email protected]>
34
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
35
 * @link      https://github.com/appserver-io/provisioning
36
 * @link      http://www.appserver.io
37
 */
38
class StandardProvisioner extends AbstractProvisioner
39
{
40
41
    /**
42
     * Path the to appserver's PHP executable on UNIX systems.
43
     *
44
     * @var string
45
     */
46
    const PHP_EXECUTABLE_UNIX = '/bin/php';
47
48
    /**
49
     * Path the to appserver's PHP executable on Windows systems.
50
     *
51
     * @var string
52
     */
53
    const PHP_EXECUTABLE_WIN = '/php/php.exe';
54
55
    /**
56
     * Provisions all web applications.
57
     *
58
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
59
     *
60
     * @return void
61
     */
62
    public function provision(ApplicationInterface $application)
63
    {
64
65
        // check if the webapps directory exists
66
        if (is_dir($webappPath = $application->getWebappPath())) {
67
            // prepare the glob expression with the application's directories to parse
68
            $applicationDirectories = $application->getEnvironmentAwareGlobPattern('{WEB-INF,META-INF}/provision', GLOB_BRACE);
0 ignored issues
show
Bug introduced by
The method getEnvironmentAwareGlobPattern() does not exist on AppserverIo\Psr\Application\ApplicationInterface. ( Ignorable by Annotation )

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

68
            /** @scrutinizer ignore-call */ 
69
            $applicationDirectories = $application->getEnvironmentAwareGlobPattern('{WEB-INF,META-INF}/provision', GLOB_BRACE);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
69
70
            // reset the annotation registry
71
            AnnotationRegistry::reset();
72
73
            // load the service instance
74
            /** @var \AppserverIo\Provisioning\Api\ProvisioningServiceInterface $service */
75
            $service = $this->getService();
76
77
            // load the configuration service instance
78
            /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */
79
            $configurationService = $this->getInitialContext()->newService('AppserverIo\Appserver\Core\Api\ConfigurationService');
80
81
            // load the container node to initialize the system properties
82
            /** @var \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface $containerNode */
83
            $containerNode = $application->getContainer()->getContainerNode();
0 ignored issues
show
Bug introduced by
The method getContainer() does not exist on AppserverIo\Psr\Application\ApplicationInterface. ( Ignorable by Annotation )

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

83
            $containerNode = $application->/** @scrutinizer ignore-call */ getContainer()->getContainerNode();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
84
85
            // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration
86
            foreach ($service->globDir($applicationDirectories, GLOB_BRACE) as $provisionFile) {
87
                try {
88
                    // validate the file, but skip it if the validation fails
89
                    $configurationService->validateFile($provisionFile, null);
90
91
                    // load the system properties
92
                    $properties = $service->getSystemProperties($containerNode, $application);
93
94
                    // create a new provision node instance and replace the properties
95
                    $provisionNode = new ProvisionNode();
96
                    $provisionNode->initFromFile($provisionFile);
97
                    $provisionNode->replaceProperties($properties);
98
99
                    // query whether we've a datasource configured or not
100
                    if ($datasource = $provisionNode->getDatasource()) {
101
                        // try to load the datasource from the system configuration
102
                        $datasourceNode = $service->findByName($datasource->getName());
0 ignored issues
show
Bug introduced by
The method findByName() does not exist on AppserverIo\Provisioning...sioningServiceInterface. ( Ignorable by Annotation )

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

102
                        /** @scrutinizer ignore-call */ 
103
                        $datasourceNode = $service->findByName($datasource->getName());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
103
                        // try to inject the datasource node if available
104
                        if ($datasourceNode != null) {
105
                            $provisionNode->injectDatasource($datasourceNode);
106
                        }
107
                    }
108
109
                    /* Re-provision the provision.xml (reinitialize).
110
                     *
111
                     * ATTENTION: The re-provisioning is extremely important, because
112
                     * this allows dynamic replacement of placeholders by using the
113
                     * XML file as a template that will reinterpreted with the PHP
114
                     * interpreter!
115
                     */
116
                    $provisionNode->reprovision($provisionFile);
117
118
                    // we've to replace the system properties again
119
                    $provisionNode->replaceProperties($properties);
120
121
                    // execute the provisioning workflow
122
                    $this->executeProvision($application, $provisionNode, new \SplFileInfo($webappPath));
123
                } catch (ConfigurationException $ce) {
124
                    // load the logger and log the XML validation errors
125
                    $systemLogger = $this->getInitialContext()->getSystemLogger();
126
                    $systemLogger->error($ce->__toString());
127
128
                    // additionally log a message that DS will be missing
129
                    $systemLogger->critical(
130
                        sprintf('Will skip reading provisioning steps in %s, provisioning might not have been done.', $provisionFile)
131
                    );
132
                }
133
            }
134
        }
135
    }
136
137
    /**
138
     * Executes the passed applications provisioning workflow.
139
     *
140
     *
141
     * @param \AppserverIo\Psr\Application\ApplicationInterface                       $application   The application instance
142
     * @param \AppserverIo\Provisioning\Configuration\ProvisionConfigurationInterface $provisionNode The file with the provisioning information
143
     * @param \SplFileInfo                                                            $webappPath    The path to the webapp folder
144
     *
145
     * @return void
146
     */
147
    protected function executeProvision(ApplicationInterface $application, ProvisionConfigurationInterface $provisionNode, \SplFileInfo $webappPath)
148
    {
149
150
        // load the steps from the configuration
151
        $stepNodes = $provisionNode->getInstallation()->getSteps();
152
        if (!is_array($stepNodes)) {
0 ignored issues
show
introduced by
The condition is_array($stepNodes) is always true.
Loading history...
153
            return;
154
        }
155
156
        // execute all steps found in the configuration
157
        foreach ($stepNodes as $stepNode) {
158
            try {
159
                // load the step node instance
160
                $step = $application->search($stepNode->getType());
161
162
                // try to inject the datasource node if available
163
                if ($datasourceNode = $provisionNode->getDatasource()) {
164
                    $step->injectDataSourceNode($datasourceNode);
165
                }
166
167
                // inject all other information
168
                $step->injectStepNode($stepNode);
169
                $step->injectApplication($application);
170
                $step->injectService($this->getService());
171
                $step->injectWebappPath($webappPath->getPathname());
172
                $step->injectInitialContext($this->getInitialContext());
173
                $step->injectPhpExecutable($this->getAbsolutPathToPhpExecutable());
174
175
                // execute the step finally
176
                $step->start(PTHREADS_INHERIT_NONE|PTHREADS_INHERIT_CONSTANTS);
177
                $step->join();
178
            } catch (\Exception $e) {
179
                $this->getInitialContext()->getSystemLogger()->error($e->__toString());
180
            }
181
        }
182
    }
183
184
    /**
185
     * Returns the absolute path to the appservers PHP executable.
186
     *
187
     * @return string The absolute path to the appserver PHP executable
188
     */
189
    public function getAbsolutPathToPhpExecutable()
190
    {
191
192
        // initialize the default path to the PHP executable
193
        $executable = StandardProvisioner::PHP_EXECUTABLE_UNIX;
194
195
        // query whether or not we're on Windows
196
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
197
            // we have a different executable on Windows systems
198
            $executable = StandardProvisioner::PHP_EXECUTABLE_WIN;
199
        }
200
201
        // return the path to the PHP executable
202
        return $this->getService()->realpath($executable);
203
    }
204
}
205