Completed
Pull Request — master (#1105)
by Tim
42:55
created

DeploymentService::loadContainerInstances()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 0
dl 0
loc 25
ccs 0
cts 10
cp 0
crap 20
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * \AppserverIo\Appserver\Core\Api\DeploymentService
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\Core\Api;
22
23
use AppserverIo\Appserver\Core\Utilities\AppEnvironmentHelper;
24
use AppserverIo\Properties\PropertiesInterface;
25
use AppserverIo\Configuration\ConfigurationException;
26
use AppserverIo\Appserver\Core\Api\Node\ContextNode;
27
use AppserverIo\Appserver\Core\Api\Node\ContainersNode;
28
use AppserverIo\Appserver\Core\Utilities\SystemPropertyKeys;
29
use AppserverIo\Psr\ApplicationServer\ContainerInterface;
30
use AppserverIo\Psr\ApplicationServer\Configuration\SystemConfigurationInterface;
31
use AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface;
32
33
/**
34
 * A service that handles deployment configuration data.
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
class DeploymentService extends AbstractFileOperationService
43
{
44
45
    /**
46
     * Returns all deployment configurations.
47
     *
48
     * @return array An array with all deployment configurations
49
     * @see \AppserverIo\Psr\ApplicationServer\ServiceInterface::findAll()
50
     */
51
    public function findAll()
52 3
    {
53
        $deploymentNodes = array();
54 3
        foreach ($this->getSystemConfiguration()->getContainers() as $container) {
55 3
            $deploymentNode = $container->getDeployment();
56 3
            $deploymentNodes[$deploymentNode->getUuid()] = $deploymentNode;
57 3
        }
58 3
        return $deploymentNodes;
59 3
    }
60
61
    /**
62
     * Returns the deployment with the passed UUID.
63
     *
64
     * @param integer $uuid UUID of the deployment to return
65
     *
66
     * @return \AppserverIo\Appserver\Core\Api\Node\\DeploymentNode The deployment with the UUID passed as parameter
0 ignored issues
show
Bug introduced by
The type AppserverIo\Appserver\Co...pi\Node\\DeploymentNode was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
67
     * @see \AppserverIo\Psr\ApplicationServer\ServiceInterface::load()
68
     */
69
    public function load($uuid)
70 2
    {
71
        $deploymentNodes = $this->findAll();
72 2
        if (array_key_exists($uuid, $deploymentNodes)) {
73 2
            return $deploymentNodes[$uuid];
74 1
        }
75
    }
76 1
77
    /**
78
     * Initializes the context instance for the passed webapp path.
79
     *
80
     * @param \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface $containerNode The container to load the context for
81
     * @param string                                                                           $webappPath    The path to the web application
82
     *
83
     * @return \AppserverIo\Appserver\Core\Api\Node\ContextNode The initialized context instance
84
     */
85
    public function loadContextInstance(ContainerConfigurationInterface $containerNode, $webappPath)
86
    {
87
88
        // prepare the context path
89
        $contextPath = basename($webappPath);
90
91
        // load the system properties
92
        $properties = $this->getSystemProperties($containerNode);
93
94
        // append the application specific properties
95
        $properties->add(SystemPropertyKeys::WEBAPP, $webappPath);
96
        $properties->add(SystemPropertyKeys::WEBAPP_NAME, $contextPath);
97
98
        // validate the base context file
99
        /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */
100
        $configurationService = $this->newService('AppserverIo\Appserver\Core\Api\ConfigurationService');
101
        $configurationService->validateFile($baseContextPath = $this->getConfdDir('context.xml'), null);
102
103
        //load it as default if validation succeeds
104
        $context = new ContextNode();
105
        $context->initFromFile($baseContextPath);
0 ignored issues
show
Bug introduced by
$baseContextPath of type string is incompatible with the type AppserverIo\Lang\String expected by parameter $filename of AppserverIo\Description\...actNode::initFromFile(). ( Ignorable by Annotation )

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

105
        $context->initFromFile(/** @scrutinizer ignore-type */ $baseContextPath);
Loading history...
106
        $context->replaceProperties($properties);
107
108
        // set the context webapp path
109
        $context->setWebappPath($webappPath);
110
111
        // try to load a context configuration (from appserver.xml) for the context path
112
        if ($contextToMerge = $containerNode->getHost()->getContext($contextPath)) {
113
            $contextToMerge->replaceProperties($properties);
114
            $context->merge($contextToMerge);
115
        }
116
117
        // iterate through all context configurations (context.xml), validate and merge them
118
        foreach ($this->globDir(AppEnvironmentHelper::getEnvironmentAwareGlobPattern($webappPath, 'META-INF/context')) as $contextFile) {
119
            try {
120
                // validate the application specific context
121
                $configurationService->validateFile($contextFile, null);
122
123
                // create a new context node instance and replace the properties
124
                $contextInstance = new ContextNode();
125
                $contextInstance->initFromFile($contextFile);
126
                $contextInstance->replaceProperties($properties);
127
128
                // merge it into the default configuration
129
                $context->merge($contextInstance);
130
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
131
            } catch (ConfigurationException $ce) {
132
                // load the logger and log the XML validation errors
133
                $systemLogger = $this->getInitialContext()->getSystemLogger();
134
                $systemLogger->error($ce->__toString());
135
136
                // additionally log a message that DS will be missing
137
                $systemLogger->critical(
138
                    sprintf('Will skip app specific context file %s, configuration might be faulty.', $contextFile)
139
                );
140
            }
141
        }
142
143
        // set the real context name
144
        $context->setName($contextPath);
145
        $context->setEnvironmentName(AppEnvironmentHelper::getEnvironmentModifier($webappPath));
146
147
        // return the initialized context instance
148
        return $context;
149
    }
150
151
    /**
152
     * Initializes the available application contexts and returns them.
153
     *
154
     * @param \AppserverIo\Psr\ApplicationServer\ContainerInterface $container The container we want to add the applications to
155
     *
156
     * @return ContextNode[] The array with the application contexts
157
     */
158
    public function loadContextInstancesByContainer(ContainerInterface $container)
159
    {
160
161
        // initialize the array for the context instances
162
        $contextInstances = array();
163
164
        // iterate over all applications and create the context configuration
165
        foreach (glob($container->getAppBase() . '/*', GLOB_ONLYDIR) as $webappPath) {
166
            $context = $this->loadContextInstance($container->getContainerNode(), $webappPath);
167
            $contextInstances[$context->getName()] = $context;
168
        }
169
170
        // return the array with the context instances
171
        return $contextInstances;
172
    }
173
174
    /**
175
     * Prepares the system properties for the actual mode.
176
     *
177
     * @param \AppserverIo\Properties\PropertiesInterface $properties The properties to prepare
178
     * @param string                                      $webappPath The path of the web application to prepare the properties with
179
     *
180
     * @return void
181
     */
182
    protected function prepareSystemProperties(PropertiesInterface $properties, $webappPath)
183
    {
184
        // append the application specific properties and replace the properties
185
        $properties->add(SystemPropertyKeys::WEBAPP, $webappPath);
186
        $properties->add(SystemPropertyKeys::WEBAPP_NAME, basename($webappPath));
187
    }
188
189
    /**
190
     * Loads the container instances from the META-INF/containers.xml configuration file of the
191
     * passed web application path and add/merge them to/with the system configuration.
192
     *
193
     * @param \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface $containerNode       The container node used for property replacement
194
     * @param \AppserverIo\Psr\ApplicationServer\Configuration\SystemConfigurationInterface    $systemConfiguration The system configuration to add/merge the found containers to/with
195
     * @param string                                                                           $webappPath          The path to the web application to search for a META-INF/containers.xml file
196
     *
197
     * @return void
198
     */
199
    public function loadContainerInstance(
200
        ContainerConfigurationInterface $containerNode,
201
        SystemConfigurationInterface $systemConfiguration,
202
        $webappPath
203
    ) {
204
205
        // load the service to validate the files
206
        /** @var \AppserverIo\Appserver\Core\Api\ConfigurationService $configurationService */
207
        $configurationService = $this->newService('AppserverIo\Appserver\Core\Api\ConfigurationService');
208
209
        // iterate through all server configurations (servers.xml), validate and merge them
210
        foreach ($this->globDir(AppEnvironmentHelper::getEnvironmentAwareGlobPattern($webappPath, 'META-INF/containers')) as $containersConfigurationFile) {
211
            try {
212
                // validate the application specific container configurations
213
                $configurationService->validateFile($containersConfigurationFile, null);
214
215
                // create a new containers node instance
216
                $containersNodeInstance = new ContainersNode();
217
                $containersNodeInstance->initFromFile($containersConfigurationFile);
218
219
                // load the system properties
220
                $properties = $this->getSystemProperties($containerNode);
221
222
                // prepare the sytsem properties
223
                $this->prepareSystemProperties($properties, $webappPath);
224
225
                /** @var \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface $containerNodeInstance */
226
                foreach ($containersNodeInstance->getContainers() as $containerNodeInstance) {
227
                    // replace the properties for the found container node instance
228
                    $containerNodeInstance->replaceProperties($properties);
229
                    // query whether we've to merge or append the server node instance
230
                    if ($container = $systemConfiguration->getContainer($containerNodeInstance->getName())) {
0 ignored issues
show
Bug introduced by
The method getContainer() does not exist on AppserverIo\Psr\Applicat...mConfigurationInterface. Did you maybe mean getContainers()? ( Ignorable by Annotation )

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

230
                    if ($container = $systemConfiguration->/** @scrutinizer ignore-call */ getContainer($containerNodeInstance->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...
231
                        $container->merge($containerNodeInstance);
232
                    } else {
233
                        $systemConfiguration->attachContainer($containerNodeInstance);
234
                    }
235
                }
236
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
237
            } catch (ConfigurationException $ce) {
238
                // load the logger and log the XML validation errors
239
                $systemLogger = $this->getInitialContext()->getSystemLogger();
240
                $systemLogger->error($ce->__toString());
241
242
                // additionally log a message that server configuration will be missing
243
                $systemLogger->critical(
244
                    sprintf(
245
                        'Will skip app specific server configuration because of invalid file %s',
246
                        $containersConfigurationFile
247
                    )
248
                );
249
            }
250
        }
251
    }
252
253
    /**
254
     * Loads the containers, defined by the applications, merges them into
255
     * the system configuration and returns the merged system configuration.
256
     *
257
     * @return \AppserverIo\Psr\ApplicationServer\Configuration\SystemConfigurationInterface The merged system configuration
258
     */
259
    public function loadContainerInstances()
260
    {
261
262
        // load the system configuration
263
        /** @var \AppserverIo\Psr\ApplicationServer\Configuration\SystemConfigurationInterface $systemConfiguration */
264
        $systemConfiguration = $this->getSystemConfiguration();
265
266
        // if applications are NOT allowed to override the system configuration
267
        if ($systemConfiguration->getAllowApplicationConfiguration() === false) {
268
            return $systemConfiguration;
269
        }
270
271
        /** @var \AppserverIo\Psr\ApplicationServer\Configuration\ContainerConfigurationInterface $containerNodeInstance */
272
        foreach ($systemConfiguration->getContainers() as $containerNode) {
273
            // load the containers application base directory
274
            $containerAppBase = $this->getBaseDirectory($containerNode->getHost()->getAppBase());
275
276
            // iterate over all applications and create the server configuration
277
            foreach (glob($containerAppBase . '/*', GLOB_ONLYDIR) as $webappPath) {
278
                $this->loadContainerInstance($containerNode, $systemConfiguration, $webappPath);
279
            }
280
        }
281
282
        // returns the merged system configuration
283
        return $systemConfiguration;
284
    }
285
}
286