diff --git a/CHANGELOG.md b/CHANGELOG.md index d2833525d..37e5cc022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,18 @@ # Version 1.0.0-beta4 # Bugfixes - -* Closed #350 - Creating EPB references by annotations + XML configuration * Closed #336 - Positioning of namespace definition next to php tag * Closed #348 - Changed determination of omitted namespaces # Features +* Closed #350 - Creating EPB references by annotations + XML configuration +* Closed #284 - Refactor Application implementation/interface * Closed #289 - Refactoring bean/servlet/manager registration in naming directory * Closed #285 - Refactor servlet engine virtual host management #285 * Closed #291 - Configuration (XML configuration) based bean declaration * Closed #300 - Timer Service doesn't support seconds as period +* Add --c start argument to change default configuration file * Add scanner for changed files in webapps directory * Remove some SPL Iteratators * Remove automatic directory parsing of appserver-io/routlt package from context.xml diff --git a/composer.json b/composer.json index 9ae123f17..04303a101 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "appserver-io/microcron" : "0.1.*", "appserver-io-psr/epb" : "0.2.*", "appserver-io-psr/servlet" : "0.7.*", + "appserver-io-psr/application" : "0.4.*", "appserver-io-psr/messagequeueprotocol" : "0.2.*", "appserver-io/doppelgaenger" : "0.4.*", "appserver-io/http" : "0.2.*", diff --git a/etc/appserver/conf.d/context.xml b/etc/appserver/conf.d/context.xml index 32d68fbdc..c7b8355bb 100644 --- a/etc/appserver/conf.d/context.xml +++ b/etc/appserver/conf.d/context.xml @@ -1,6 +1,13 @@ - + + + load($configurationFileName); +// create a DOMElement with the base.dir configuration +$paramElement = $configurationFile->createElement('param', APPSERVER_BP); +$paramElement->setAttribute('name', DirectoryKeys::BASE); +$paramElement->setAttribute('type', ParamNode::TYPE_STRING); + +// append the base.dir DOMElement +if ($paramsNode = $configurationFile->getElementsByTagName('params')->item(0)) { + $paramsNode->appendChild($paramElement); +} + +// create a new DOMDocument with the merge content => necessary because else, schema validation fails!! +$mergeDoc = new \DOMDocument(); +$mergeDoc->loadXML($configurationFile->saveXML()); + // activate internal error handling, necessary to catch errors with libxml_get_errors() libxml_use_internal_errors(true); // validate the configuration file with the schema -if ($configurationFile->schemaValidate($schemaFileName) === false) { +if ($mergeDoc->schemaValidate($schemaFileName) === false) { foreach (libxml_get_errors() as $error) { $message = "Found a schema validation error on line %s with code %s and message %s when validating configuration file %s"; error_log(var_export($error, true)); @@ -68,16 +102,11 @@ // initialize the SimpleXMLElement with the content XML configuration file $configuration = new \AppserverIo\Configuration\Configuration(); -$configuration->initFromFile($configurationFileName); -$configuration->addChildWithNameAndValue('baseDirectory', APPSERVER_BP); +$configuration->initFromString($mergeDoc->saveXML()); // create the server instance $server = new Server($configuration); -// check if server.php has been started with -w option -$watch = 'w'; -$arguments = getopt("$watch::"); - // if -w option has been passed, watch deployment directory only if (array_key_exists($watch, $arguments)) { $server->watch(); diff --git a/src/AppserverIo/Appserver/Application/Application.php b/src/AppserverIo/Appserver/Application/Application.php index 89bf5aaec..2b0e535c1 100644 --- a/src/AppserverIo/Appserver/Application/Application.php +++ b/src/AppserverIo/Appserver/Application/Application.php @@ -21,21 +21,23 @@ namespace AppserverIo\Appserver\Application; +use AppserverIo\Lang\Reflection\ReflectionObject; +use AppserverIo\Logger\LoggerUtils; +use AppserverIo\Storage\GenericStackable; +use AppserverIo\Storage\StorageInterface; use AppserverIo\Appserver\Core\Api\Node\ClassLoaderNodeInterface; use AppserverIo\Appserver\Core\Interfaces\ClassLoaderInterface; use AppserverIo\Appserver\Naming\BindingTrait; -use AppserverIo\Logger\LoggerUtils; use AppserverIo\Appserver\Naming\NamingDirectory; use AppserverIo\Psr\Naming\NamingException; use AppserverIo\Psr\Naming\NamingDirectoryInterface; -use AppserverIo\Storage\GenericStackable; -use AppserverIo\Storage\StorageInterface; -use AppserverIo\Lang\Reflection\ReflectionObject; use AppserverIo\Psr\EnterpriseBeans\Annotations\EnterpriseBean; use AppserverIo\Psr\EnterpriseBeans\Annotations\AnnotationKeys; use AppserverIo\Psr\Application\ManagerInterface; -use AppserverIo\Appserver\Application\Interfaces\ContextInterface; use AppserverIo\Psr\Application\ApplicationInterface; +use AppserverIo\Psr\Application\DirectoryAwareInterface; +use AppserverIo\Psr\Application\FilesystemAwareInterface; +use AppserverIo\Appserver\Application\Interfaces\ContextInterface; use AppserverIo\Appserver\Application\Interfaces\ManagerConfigurationInterface; /** @@ -60,7 +62,7 @@ * @property string $name Name of the application * @property \AppserverIo\Psr\Naming\NamingDirectoryInterface $namingDirectory The naming directory instance */ -class Application extends \Thread implements ApplicationInterface +class Application extends \Thread implements ApplicationInterface, DirectoryAwareInterface, FilesystemAwareInterface { /** @@ -337,23 +339,23 @@ public function getBaseDirectory($directoryToAppend = null) } /** - * Returns the absolute path to the web application base directory. + * Returns the absolute path to the applications base directory. * - * @return string The path to the webapps folder + * @return string The app base directory */ - public function getWebappPath() + public function getAppBase() { - return $this->getAppBase() . DIRECTORY_SEPARATOR . $this->getName(); + return $this->getNamingDirectory()->search('php:env/appBase'); } /** - * Returns the absolute path to the applications base directory. + * Returns the absolute path to the web application base directory. * - * @return string The app base directory + * @return string The path to the webapps folder */ - public function getAppBase() + public function getWebappPath() { - return $this->getNamingDirectory()->search('php:env/appBase'); + return $this->getNamingDirectory()->search(sprintf('php:env/%s/webappPath', $this->getName())); } /** @@ -373,7 +375,7 @@ public function getTmpDir() */ public function getSessionDir() { - return $this->getTmpDir() . DIRECTORY_SEPARATOR . ApplicationInterface::SESSION_DIRECTORY; + return $this->getNamingDirectory()->search(sprintf('php:env/%s/sessionDirectory', $this->getName())); } /** @@ -383,7 +385,7 @@ public function getSessionDir() */ public function getCacheDir() { - return $this->getTmpDir() . DIRECTORY_SEPARATOR . ApplicationInterface::CACHE_DIRECTORY; + return $this->getNamingDirectory()->search(sprintf('php:env/%s/cacheDirectory', $this->getName())); } /** diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index 6195b8b43..6b5429489 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -20,11 +20,10 @@ use AppserverIo\Logger\LoggerUtils; use AppserverIo\Storage\GenericStackable; +use AppserverIo\Appserver\Naming\NamingDirectory; use AppserverIo\Psr\Application\ApplicationInterface; use AppserverIo\Appserver\Core\Interfaces\ContainerInterface; -use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; use AppserverIo\Appserver\Core\Utilities\ContainerStateKeys; -use AppserverIo\Appserver\Naming\NamingDirectory; /** * Class AbstractContainerThread @@ -147,8 +146,7 @@ public function main() // define webservers base dir define( 'SERVER_BASEDIR', - $this->getInitialContext()->getSystemConfiguration()->getBaseDirectory()->getNodeValue()->__toString() - . DIRECTORY_SEPARATOR + $this->getInitialContext()->getSystemConfiguration()->getBaseDirectory() . DIRECTORY_SEPARATOR ); // check if we've the old or the new directory structure diff --git a/src/AppserverIo/Appserver/Core/AbstractExtractor.php b/src/AppserverIo/Appserver/Core/AbstractExtractor.php index 08d1a36d2..df36d598c 100644 --- a/src/AppserverIo/Appserver/Core/AbstractExtractor.php +++ b/src/AppserverIo/Appserver/Core/AbstractExtractor.php @@ -17,7 +17,6 @@ namespace AppserverIo\Appserver\Core; use AppserverIo\Appserver\Application\Interfaces\ContextInterface; -use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; use AppserverIo\Appserver\Core\Interfaces\ExtractorInterface; use AppserverIo\Appserver\Core\Api\Node\ExtractorNodeInterface; @@ -108,9 +107,7 @@ public function deployWebapps() } // prepare the filename for the file with the last succesfull deployment timestamp - $successFile = $this->getService()->realpath( - DirectoryKeys::DEPLOY . DIRECTORY_SEPARATOR . ExtractorInterface::FILE_DEPLOYMENT_SUCCESSFULL - ); + $successFile = $this->getService()->getDeployDir(ExtractorInterface::FILE_DEPLOYMENT_SUCCESSFULL); // create a flag file with date of the last successfull deployment touch($successFile); @@ -129,7 +126,7 @@ public function flagArchive(\SplFileInfo $archive, $flag) // delete all old flags $this->unflagArchive($archive); // get archives folder name from deploy dir - $deployFolderName = $this->getDeployDir() . DIRECTORY_SEPARATOR . $archive->getFilename(); + $deployFolderName = $this->getDeployDir($archive->getFilename()); // flag archive file_put_contents($deployFolderName . $flag, $archive->getFilename()); // set correct user/group for the flag file @@ -165,7 +162,7 @@ public function isDeployable(\SplFileInfo $archive) { // prepare the deploy folder - $deployFolderName = $this->getDeployDir() . DIRECTORY_SEPARATOR . $archive->getFilename(); + $deployFolderName = $this->getDeployDir($archive->getFilename()); // check if the .dodeploy flag file exists if (file_exists($deployFolderName . ExtractorInterface::FLAG_DODEPLOY)) { @@ -188,7 +185,7 @@ public function isUndeployable(\SplFileInfo $archive) { // prepare the deploy folder - $deployFolderName = $this->getDeployDir() . DIRECTORY_SEPARATOR . $archive->getFilename(); + $deployFolderName = $this->getDeployDir($archive->getFilename()); // make sure that NO flag for the archive is available foreach ($this->getFlags() as $flag) { @@ -213,8 +210,7 @@ public function soakArchive(\SplFileInfo $archive) { // prepare the upload target in the deploy directory - $deployDirectory = $this->getDeployDir(); - $target = $deployDirectory . DIRECTORY_SEPARATOR . $archive->getFilename(); + $target = $this->getDeployDir($archive->getFilename()); // move the uploaded file from the tmp to the deploy directory rename($archive->getPathname(), $target); @@ -238,7 +234,7 @@ public function undeployArchive(\SplFileInfo $archive) // create webapp folder name based on the archive's basename $webappFolderName = new \SplFileInfo( - $this->getWebappsDir() . DIRECTORY_SEPARATOR . basename($archive->getFilename(), $this->getExtensionSuffix()) + $this->getWebappsDir(basename($archive->getFilename(), $this->getExtensionSuffix())) ); // check if app has to be undeployed @@ -258,10 +254,10 @@ public function undeployArchive(\SplFileInfo $archive) } } catch (\Exception $e) { + // log error - $this->getInitialContext() - ->getSystemLogger() - ->error($e->__toString()); + $this->getInitialContext()->getSystemLogger()->error($e->__toString()); + // flag webapp as failed $this->flagArchive($archive, ExtractorInterface::FLAG_FAILED); } @@ -283,10 +279,8 @@ public function restoreBackup(\SplFileInfo $archive) } // create tmp & webapp folder name based on the archive's basename - $webappFolderName = $this->getWebappsDir() . DIRECTORY_SEPARATOR - . basename($archive->getFilename(), $this->getExtensionSuffix()); - $tmpFolderName = $this->getTmpDir() . DIRECTORY_SEPARATOR - . md5(basename($archive->getFilename(), $this->getExtensionSuffix())); + $webappFolderName = $this->getWebappsDir(basename($archive->getFilename(), $this->getExtensionSuffix())); + $tmpFolderName = $this->getTmpDir(md5(basename($archive->getFilename(), $this->getExtensionSuffix()))); // copy backup to webapp directory $this->copyDir($tmpFolderName, $webappFolderName); @@ -361,31 +355,37 @@ public function getService() /** * Returns the servers tmp directory. * + * @param string $relativePathToAppend A relative path to append + * * @return string */ - public function getTmpDir() + public function getTmpDir($relativePathToAppend = '') { - return $this->getService()->getTmpDir(); + return $this->getService()->getTmpDir($relativePathToAppend); } /** * Returns the servers deploy directory. * + * @param string $relativePathToAppend A relative path to append + * * @return string */ - public function getDeployDir() + public function getDeployDir($relativePathToAppend = '') { - return $this->getService()->getDeployDir(); + return $this->getService()->getDeployDir($relativePathToAppend); } /** * Returns the servers webapps directory. * + * @param string $relativePathToAppend A relative path to append + * * @return string The web application directory */ - public function getWebappsDir() + public function getWebappsDir($relativePathToAppend = '') { - return $this->getService()->getWebappsDir(); + return $this->getService()->getWebappsDir($relativePathToAppend); } /** diff --git a/src/AppserverIo/Appserver/Core/AbstractManager.php b/src/AppserverIo/Appserver/Core/AbstractManager.php index ad317a1a0..52178bf0d 100644 --- a/src/AppserverIo/Appserver/Core/AbstractManager.php +++ b/src/AppserverIo/Appserver/Core/AbstractManager.php @@ -23,16 +23,16 @@ namespace AppserverIo\Appserver\Core; +use AppserverIo\Lang\Reflection\ReflectionClass; use AppserverIo\Storage\StorageInterface; use AppserverIo\Storage\GenericStackable; use AppserverIo\Psr\Naming\NamingException; use AppserverIo\Psr\Application\ManagerInterface; use AppserverIo\Psr\Application\ApplicationInterface; -use AppserverIo\Appserver\Naming\InitialContext; use AppserverIo\Appserver\DependencyInjectionContainer\Description\EpbReferenceDescriptor; use AppserverIo\Appserver\DependencyInjectionContainer\Interfaces\EpbReferenceDescriptorInterface; use AppserverIo\Appserver\DependencyInjectionContainer\Interfaces\ResReferenceDescriptorInterface; -use AppserverIo\Lang\Reflection\ReflectionClass; +use AppserverIo\Appserver\Naming\InitialContext as NamingDirectory; /** * Abstract manager implementation. @@ -91,7 +91,7 @@ public function getApplication() * * @return void */ - public function injectInitialContext(InitialContext $initialContext) + public function injectInitialContext(NamingDirectory $initialContext) { $this->initialContext = $initialContext; } diff --git a/src/AppserverIo/Appserver/Core/Api/AbstractService.php b/src/AppserverIo/Appserver/Core/Api/AbstractService.php index 14a4234fa..a4969044d 100644 --- a/src/AppserverIo/Appserver/Core/Api/AbstractService.php +++ b/src/AppserverIo/Appserver/Core/Api/AbstractService.php @@ -145,10 +145,7 @@ public function getBaseDirectory($directoryToAppend = null) { // load the base directory from the system configuration - $baseDirectory = $this->getSystemConfiguration() - ->getBaseDirectory() - ->getNodeValue() - ->__toString(); + $baseDirectory = $this->getSystemConfiguration()->getBaseDirectory(); // if a directory has been passed, make it absolute and append it if ($directoryToAppend != null) { @@ -160,13 +157,23 @@ public function getBaseDirectory($directoryToAppend = null) } /** - * Return's the directory structure to be created at first start. + * Returns the directory structure to be created at first start. * * @return array The directory structure to be created if necessary */ public function getDirectories() { - return DirectoryKeys::getDirectories(); + + // initialize the array with the directories + $directories = array(); + + // iterate over the directory keys and read the configuration values + foreach (DirectoryKeys::getServerDirectoryKeys() as $directoryKey) { + $directories[$directoryKey] = $this->getSystemConfiguration()->getParam($directoryKey); + } + + // return the array with the directories + return $directories; } /** @@ -192,7 +199,11 @@ protected function makePathAbsolute($path = '') */ public function getTmpDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::TMP . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::TMP) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** @@ -204,7 +215,11 @@ public function getTmpDir($relativePathToAppend = '') */ public function getDeployDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::DEPLOY . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::DEPLOY) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** @@ -216,7 +231,11 @@ public function getDeployDir($relativePathToAppend = '') */ public function getWebappsDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::WEBAPPS . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::WEBAPPS) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** @@ -228,7 +247,11 @@ public function getWebappsDir($relativePathToAppend = '') */ public function getLogDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::LOG . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::LOG) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** @@ -240,7 +263,11 @@ public function getLogDir($relativePathToAppend = '') */ public function getConfDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::CONF . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::CONF) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** @@ -252,7 +279,11 @@ public function getConfDir($relativePathToAppend = '') */ public function getConfdDir($relativePathToAppend = '') { - return $this->realpath($this->makePathAbsolute(DirectoryKeys::CONFD . $this->makePathAbsolute($relativePathToAppend))); + return $this->realpath( + $this->makePathAbsolute( + $this->getSystemConfiguration()->getParam(DirectoryKeys::CONFD) . $this->makePathAbsolute($relativePathToAppend) + ) + ); } /** diff --git a/src/AppserverIo/Appserver/Core/Api/DeploymentService.php b/src/AppserverIo/Appserver/Core/Api/DeploymentService.php index 9d5b3e519..909237945 100644 --- a/src/AppserverIo/Appserver/Core/Api/DeploymentService.php +++ b/src/AppserverIo/Appserver/Core/Api/DeploymentService.php @@ -1,4 +1,5 @@ initDefaultDirectories(); $this->initDefaultLoggers(); $this->initDefaultScanners(); $this->initDefaultExtractors(); @@ -115,12 +117,28 @@ public function __construct() $this->initDefaultInitialContext(); } + /** + * Initialize the default directories. + * + * @return void + */ + public function initDefaultDirectories() + { + $this->setParam(DirectoryKeys::LOG, ParamNode::TYPE_STRING, '/var/log'); + $this->setParam(DirectoryKeys::RUN, ParamNode::TYPE_STRING, '/var/run'); + $this->setParam(DirectoryKeys::TMP, ParamNode::TYPE_STRING, '/var/tmp'); + $this->setParam(DirectoryKeys::DEPLOY, ParamNode::TYPE_STRING, '/deploy'); + $this->setParam(DirectoryKeys::WEBAPPS, ParamNode::TYPE_STRING, '/webapps'); + $this->setParam(DirectoryKeys::CONF, ParamNode::TYPE_STRING, '/etc/appserver'); + $this->setParam(DirectoryKeys::CONFD, ParamNode::TYPE_STRING, '/etc/appserver/conf.d'); + } + /** * Initializes the default initial context configuration. * * @return void */ - public function initDefaultInitialContext() + protected function initDefaultInitialContext() { // initialize the configuration values for the initial context @@ -277,32 +295,20 @@ public function getUmask() $this->getParam('umask'); } - /** - * Sets the passed base directory node. - * - * @param \AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode $baseDirectory The base directory node to set - * - * @return void - */ - public function setBaseDirectory($baseDirectory) - { - $this->baseDirectory = $baseDirectory; - } - /** * Returns the node with the base directory information. * - * @return \AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode The base directory information + * @return string The base directory information */ public function getBaseDirectory() { - return $this->baseDirectory; + return $this->getParam(DirectoryKeys::BASE); } /** * Returns the node containing information about the initial context. * - * @return \AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode The initial context information + * @return \AppserverIo\Appserver\Core\Api\Node\InitialContextNode The initial context information */ public function getInitialContext() { diff --git a/src/AppserverIo/Appserver/Core/Api/Node/ContextNode.php b/src/AppserverIo/Appserver/Core/Api/Node/ContextNode.php index fb8961c6c..5f728b94c 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/ContextNode.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/ContextNode.php @@ -16,6 +16,8 @@ namespace AppserverIo\Appserver\Core\Api\Node; +use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; + /** * DTO to transfer server information. * @@ -30,11 +32,28 @@ */ class ContextNode extends AbstractNode { - // We use several traits which give us the possibility to have collections of the child nodes mentioned in the - // corresponding trait name + + /** + * A class loader trait. + * + * @var \TraitInterface + */ use ClassLoadersNodeTrait; + + /** + * A managers node trait. + * + * @var \TraitInterface + */ use ManagersNodeTrait; + /** + * A params node trait. + * + * @var \TraitInterface + */ + use ParamsNodeTrait; + /** * The context name, * @@ -54,13 +73,31 @@ class ContextNode extends AbstractNode /** * Initializes the context configuration with the passed values. * - * @param string $name The context name - * @param string $type The context class name + * @param string $name The context name + * @param string $type The context class name + * @param array $params The context params */ - public function __construct($name = '', $type = '') + public function __construct($name = '', $type = '', array $params = array()) { + + // set name and type $this->name = $name; $this->type = $type; + $this->params = $params; + + // initialize the default directories + $this->initDefaultDirectories(); + } + + /** + * Initialize the default directories. + * + * @return void + */ + public function initDefaultDirectories() + { + $this->setParam(DirectoryKeys::CACHE, ParamNode::TYPE_STRING, '/cache'); + $this->setParam(DirectoryKeys::SESSION, ParamNode::TYPE_STRING, '/session'); } /** @@ -95,6 +132,26 @@ public function getType() public function merge(ContextNode $contextNode) { + // load the params defined in this context + $localParams = $this->getParams(); + + // merge them with the passed ones + foreach ($contextNode->getParams() as $paramToMerge) { + $isMerged = false; + foreach ($localParams as $key => $param) { + if ($param->getName() == $paramToMerge->getName()) { + $localParams[$key] = $paramToMerge; + $isMerged = true; + } + } + if ($isMerged === false) { + $localParams[$paramToMerge->getUuid()] = $paramToMerge; + } + } + + // set the params back to the context + $this->setParams($localParams); + // load the managers defined of this context $localManagers = $this->getManagers(); diff --git a/src/AppserverIo/Appserver/Core/Api/Node/ParamNode.php b/src/AppserverIo/Appserver/Core/Api/Node/ParamNode.php index c32a9e880..1ca60f8bb 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/ParamNode.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/ParamNode.php @@ -31,6 +31,27 @@ class ParamNode extends AbstractValueNode { + /** + * The constant for the param type 'string'; + * + * @var string + */ + const TYPE_STRING = 'string'; + + /** + * The constant for the param type 'boolean'; + * + * @var string + */ + const TYPE_BOOLEAN = 'boolean'; + + /** + * The constant for the param type 'integer'; + * + * @var string + */ + const TYPE_INTEGER = 'integer'; + /** * The paramss name. * diff --git a/src/AppserverIo/Appserver/Core/Api/Node/ParamsNodeTrait.php b/src/AppserverIo/Appserver/Core/Api/Node/ParamsNodeTrait.php index 5a9eb6b2f..9563381b2 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/ParamsNodeTrait.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/ParamsNodeTrait.php @@ -67,6 +67,33 @@ public function setParams(array $params) $this->params = $params; } + /** + * Sets the param with the passed name, type and value. + * + * @param string $name The param name + * @param string $type The param type + * @param mixed $value The param value + * + * @return void + */ + public function setParam($name, $type, $value) + { + + // initialize the param to set + $paramToSet = new ParamNode($name, $type, new NodeValue($value)); + + // query whether a param with this name has already been set + foreach ($this->params as $key => $param) { + if ($param->getName() === $paramToSet->getName()) { // override the param + $this->params[$key] = $paramToSet; + return; + } + } + + // append the param + $this->params[] = $paramToSet; + } + /** * Returns the param with the passed name casted to * the specified type. diff --git a/src/AppserverIo/Appserver/Core/GenericDeployment.php b/src/AppserverIo/Appserver/Core/GenericDeployment.php index 4bc2e6767..cbacde2ec 100644 --- a/src/AppserverIo/Appserver/Core/GenericDeployment.php +++ b/src/AppserverIo/Appserver/Core/GenericDeployment.php @@ -24,13 +24,13 @@ use AppserverIo\Storage\GenericStackable; use AppserverIo\Storage\StackableStorage; +use AppserverIo\Appserver\Naming\NamingDirectory; use AppserverIo\Appserver\Application\Application; use AppserverIo\Appserver\Application\Interfaces\ContextInterface; use AppserverIo\Appserver\Core\AbstractDeployment; -use AppserverIo\Appserver\Core\Interfaces\ContainerInterface; -use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; use AppserverIo\Appserver\Core\Api\Node\ContextNode; -use AppserverIo\Appserver\Naming\NamingDirectory; +use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; +use AppserverIo\Appserver\Core\Interfaces\ContainerInterface; /** * Generic deployment implementation for web applications. @@ -46,6 +46,13 @@ class GenericDeployment extends AbstractDeployment { + /** + * Array containing the application specific 'env' naming directories. + * + * @var array + */ + protected $envAppDirs = array(); + /** * Initializes the available applications and adds them to the deployment instance. * @@ -73,9 +80,6 @@ public function deploy(ContainerInterface $container) // at least a WEB-INF or META-INF folder has to be available if (is_dir($webInfDir) || is_dir($metaInfDir)) { - // lock the mutex before application initialization - \Mutex::lock($mutex); - // this IS the unique application name $applicationName = basename($folder); @@ -106,11 +110,19 @@ public function deploy(ContainerInterface $container) $globalDir = $namingDirectory->search('php:global'); $globalDir->bind($applicationName, $application); - // register the applications temporary directory in the naming directory + // prepare the application specific directories + $webappPath = sprintf('%s/%s', $namingDirectory->search('env/appBase'), $applicationName); $tmpDirectory = sprintf('%s/%s', $namingDirectory->search('env/tmpDirectory'), $applicationName); + $cacheDirectory = sprintf('%s/%s', $tmpDirectory, ltrim($context->getParam(DirectoryKeys::CACHE, '/'))); + $sessionDirectory = sprintf('%s/%s', $tmpDirectory, ltrim($context->getParam(DirectoryKeys::SESSION, '/'))); + + // register the applications temporary directory in the naming directory list ($envDir, ) = $namingDirectory->getAttribute('env'); - $envAppDir = $envDir->createSubdirectory($applicationName); - $envAppDir->bind('tmpDirectory', $tmpDirectory); + $this->envAppDirs[$applicationName] = $envDir->createSubdirectory($applicationName); + $this->envAppDirs[$applicationName]->bind('webappPath', $webappPath); + $this->envAppDirs[$applicationName]->bind('tmpDirectory', $tmpDirectory); + $this->envAppDirs[$applicationName]->bind('cacheDirectory', $cacheDirectory); + $this->envAppDirs[$applicationName]->bind('sessionDirectory', $sessionDirectory); // create the applications temporary folders and cleans the folders up $this->getDeploymentService()->createTmpFolders($application); @@ -145,9 +157,6 @@ public function deploy(ContainerInterface $container) // add the application to the container $container->addApplication($application); - // unlock the mutex after application initialization - \Mutex::unlock($mutex); - } else { // if we can't find WEB-INF or META-INF directory // write a log message, that the folder doesn't contain a valid application diff --git a/src/AppserverIo/Appserver/Core/Scanner/HeartbeatScanner.php b/src/AppserverIo/Appserver/Core/Scanner/HeartbeatScanner.php index 776323843..ab46b87d2 100644 --- a/src/AppserverIo/Appserver/Core/Scanner/HeartbeatScanner.php +++ b/src/AppserverIo/Appserver/Core/Scanner/HeartbeatScanner.php @@ -95,6 +95,7 @@ public function getHeartbeatFile() */ public function main() { + // log the configured deployment directory $this->getSystemLogger()->debug( sprintf( diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 150ec3e7e..ef5d7beae 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -399,24 +399,6 @@ public function getProvisioners() return $this->provisioners; } - /** - * Will safely put the appserver to rest by cleaning up after the last run - * - * @return void - */ - public function cleanup() - { - // We need to delete the heartbeat file as the watcher might restart the appserver otherwise - unlink( - $this->getSystemConfiguration() - ->getBaseDirectory() - ->getNodeValue() - ->__toString() . DIRECTORY_SEPARATOR . - DirectoryKeys::RUN . DIRECTORY_SEPARATOR . - HeartbeatScanner::HEARTBEAT_FILE_NAME - ); - } - /** * Start the container threads. * @@ -436,10 +418,7 @@ public function start() $this->getSystemLogger()->info( sprintf( 'Server successfully started in basedirectory %s ', - $this->getSystemConfiguration() - ->getBaseDirectory() - ->getNodeValue() - ->__toString() + $this->getSystemConfiguration()->getBaseDirectory() ) ); @@ -468,33 +447,6 @@ public function profile() } } - /** - * Starts giving the heartbeat to tell everyone we are alive. - * This will keep your server in an endless loop, so be wary! - * - * @return void - * - * @TODO integrate this into a maintenance layer - */ - protected function initHeartbeat() - { - while (true) { - - // Tell them we are alive - touch( - $this->getSystemConfiguration() - ->getBaseDirectory() - ->getNodeValue() - ->__toString() . DIRECTORY_SEPARATOR . - DirectoryKeys::RUN . DIRECTORY_SEPARATOR . - HeartbeatScanner::HEARTBEAT_FILE_NAME - ); - - // Sleep a little - sleep(1); - } - } - /** * Scan's the deployment directory for changes and restarts * the server instance if necessary. @@ -675,4 +627,45 @@ public function newService($className) { return $this->getInitialContext()->newService($className); } + + /** + * Will safely put the appserver to rest by cleaning up after the last run + * + * @return void + */ + public function cleanup() + { + // We need to delete the heartbeat file as the watcher might restart the appserver otherwise + unlink( + $this->getSystemConfiguration() + ->getBaseDirectory() . DIRECTORY_SEPARATOR . + DirectoryKeys::RUN . DIRECTORY_SEPARATOR . + HeartbeatScanner::HEARTBEAT_FILE_NAME + ); + } + + /** + * Starts giving the heartbeat to tell everyone we are alive. + * This will keep your server in an endless loop, so be wary! + * + * @return void + * + * @TODO integrate this into a maintenance layer + */ + protected function initHeartbeat() + { + while (true) { + + // Tell them we are alive + touch( + $this->getSystemConfiguration() + ->getBaseDirectory() . DIRECTORY_SEPARATOR . + DirectoryKeys::RUN . DIRECTORY_SEPARATOR . + HeartbeatScanner::HEARTBEAT_FILE_NAME + ); + + // Sleep a little + sleep(1); + } + } } diff --git a/src/AppserverIo/Appserver/Core/Utilities/DirectoryKeys.php b/src/AppserverIo/Appserver/Core/Utilities/DirectoryKeys.php index 9aab96795..468ddb4d4 100644 --- a/src/AppserverIo/Appserver/Core/Utilities/DirectoryKeys.php +++ b/src/AppserverIo/Appserver/Core/Utilities/DirectoryKeys.php @@ -1,4 +1,5 @@ namingDirectory = new NamingDirectory(); $this->namingDirectory->setScheme('php'); $this->envDir = $this->namingDirectory->createSubdirectory('env'); + $this->appDir = $this->envDir->createSubdirectory('foo'); $this->namingDirectory->bind('php:global/foo', $this->application); $this->namingDirectory->bind('php:env/user', ApplicationTest::USER); $this->namingDirectory->bind('php:env/group', ApplicationTest::GROUP); $this->namingDirectory->bind('php:env/umask', ApplicationTest::UMASK); $this->namingDirectory->bind('php:env/tmpDirectory', ApplicationTest::GLOBAL_TMP_DIR); + $this->namingDirectory->bind('php:env/foo/webappPath', ApplicationTest::WEBAPP_PATH); $this->namingDirectory->bind('php:env/foo/tmpDirectory', ApplicationTest::TMP_DIR); + $this->namingDirectory->bind('php:env/foo/cacheDirectory', ApplicationTest::CACHE_DIR); + $this->namingDirectory->bind('php:env/foo/sessionDirectory', ApplicationTest::SESSION_DIR); $this->namingDirectory->bind('php:env/baseDirectory', ApplicationTest::BASE_DIRECTORY); $this->namingDirectory->bind('php:env/appBase', ApplicationTest::APP_BASE); @@ -228,8 +253,7 @@ public function testGetClassLoader() */ public function testGetSessionDir() { - $sessionDir = ApplicationTest::TMP_DIR . DIRECTORY_SEPARATOR . ApplicationInterface::SESSION_DIRECTORY; - $this->assertEquals($sessionDir, $this->application->getSessionDir()); + $this->assertEquals(ApplicationTest::SESSION_DIR, $this->application->getSessionDir()); } /** @@ -239,8 +263,7 @@ public function testGetSessionDir() */ public function testGetCacheDir() { - $cacheDir = ApplicationTest::TMP_DIR . DIRECTORY_SEPARATOR . ApplicationInterface::CACHE_DIRECTORY; - $this->assertEquals($cacheDir, $this->application->getCacheDir()); + $this->assertEquals(ApplicationTest::CACHE_DIR, $this->application->getCacheDir()); } /** @@ -336,12 +359,7 @@ public function testGetBaseDirectoryWithDirectoryToAppend() */ public function testGetWebappPath() { - - // prepare the expected webapp path - $webappPath = ApplicationTest::APP_BASE . DIRECTORY_SEPARATOR . ApplicationTest::NAME; - - // inject the path components - $this->assertEquals($webappPath, $this->application->getWebappPath()); + $this->assertEquals(ApplicationTest::WEBAPP_PATH, $this->application->getWebappPath()); } /** diff --git a/tests/AppserverIo/Appserver/Core/Api/Node/AppserverNodeTest.php b/tests/AppserverIo/Appserver/Core/Api/Node/AppserverNodeTest.php index bcd03aa57..1712ec38e 100644 --- a/tests/AppserverIo/Appserver/Core/Api/Node/AppserverNodeTest.php +++ b/tests/AppserverIo/Appserver/Core/Api/Node/AppserverNodeTest.php @@ -48,8 +48,7 @@ public function setUp() */ public function testGetBaseDirectory() { - $baseDirectory = $this->appserverNode->getBaseDirectory(); - $this->assertInstanceOf('AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode', $baseDirectory); + $this->assertSame('/opt/appserver', $this->appserverNode->getBaseDirectory()); } /** diff --git a/tests/AppserverIo/Appserver/Core/ServerTest.php b/tests/AppserverIo/Appserver/Core/ServerTest.php index e921364b1..bc832bf9e 100644 --- a/tests/AppserverIo/Appserver/Core/ServerTest.php +++ b/tests/AppserverIo/Appserver/Core/ServerTest.php @@ -19,41 +19,40 @@ * * @package AppserverIo\Appserver\Core * @copyright Copyright (c) 2010 - TechDivision GmbH - * @license http://opensource.org/licenses/osl-3.0.php - * Open Software License (OSL 3.0) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @author Tim Wagner */ class ServerTest extends AbstractTest { /** - * The server instance to test. + * Creates and returns a mock server instance with NO methods mocked. * - * @var AppserverIo\Appserver\Core\Server - */ - protected $server; - - /** - * Initializes the server instance to test. + * @param array $methodsToMock The methods we want to mock + * @param boolean $callOriginalConstructor TRUE if the original constructor should be invoked, else FALSE * - * @return void + * @return PHPUnit_Framework_MockObject_MockObject The mocked server instance */ - public function setUp() + public function getMockServer(array $methodsToMock = array(), $callOriginalConstructor = true) { + // initialize the configuration $configuration = $this->getAppserverConfiguration(); - // replace the base directory - $appserverConfiguration = new Configuration(); - $appserverConfiguration->setNodeName('appserver'); - $baseDirectoryConfiguration = new Configuration(); - $baseDirectoryConfiguration->setNodeName('baseDirectory'); - $baseDirectoryConfiguration->setValue(__DIR__); - $appserverConfiguration->addChild($baseDirectoryConfiguration); - $configuration->merge($appserverConfiguration); + // create a new mock server implementation + return $this->getMock('AppserverIo\Appserver\Core\Server', $methodsToMock, array($configuration), '', $callOriginalConstructor); + } - // initialize the server instance - $this->server = new Server($configuration); + /** + * Creates and returns a mock logger instance with all methods mocked. + * + * @param array $methodsToMock The methods we want to mock + * + * @return PHPUnit_Framework_MockObject_MockObject The mocked logger instance + */ + public function getMockLogger(array $methodsToMock = array('log', 'error', 'warning', 'notice', 'emergency', 'debug', 'info', 'alert', 'critical')) + { + return $this->getMock('Psr\Log\LoggerInterface', $methodsToMock); } /** @@ -63,7 +62,12 @@ public function setUp() */ public function testGetInitialContext() { - $this->assertInstanceOf('AppserverIo\Appserver\Core\InitialContext', $this->server->getInitialContext()); + + // initialize the mock server + $mockServer = $this->getMockServer(array('initUmask','initFileSystem', 'initSslCertificate')); + + // check the initial context type + $this->assertInstanceOf('AppserverIo\Appserver\Core\InitialContext', $mockServer->getInitialContext()); } /** @@ -73,7 +77,12 @@ public function testGetInitialContext() */ public function testGetSystemLogger() { - $this->assertInstanceOf('Monolog\Logger', $this->server->getSystemLogger()); + + // initialize the mock server + $mockServer = $this->getMockServer(array('initUmask','initFileSystem', 'initSslCertificate')); + + // check the logger configuration type + $this->assertInstanceOf('Monolog\Logger', $mockServer->getSystemLogger()); } /** @@ -83,7 +92,12 @@ public function testGetSystemLogger() */ public function testGetSystemConfiguration() { - $this->assertInstanceOf('AppserverIo\Appserver\Core\Api\Node\AppserverNode', $this->server->getSystemConfiguration()); + + // initialize the mock server + $mockServer = $this->getMockServer(array('initUmask','initFileSystem', 'initSslCertificate')); + + // check the system configuration type + $this->assertInstanceOf('AppserverIo\Appserver\Core\Api\Node\AppserverNode', $mockServer->getSystemConfiguration()); } /** @@ -106,17 +120,49 @@ public function testStart() $appserverConfiguration->addChild($baseDirectoryConfiguration); $configuration->merge($appserverConfiguration); + // initialize the mock logger + $mockLogger = $this->getMockLogger(); + + // mock the system configuration + $mockSystemConfiguration = $this->getMock( + 'AppserverIo\Appserver\Core\Api\Node\AppserverNode', + array('getBaseDirectory') + ); + // create a new mock server implementation - $server = $this->getMock('AppserverIo\Appserver\Core\Server', array('startContainers'), array($configuration)); + $server = $this->getMock( + 'AppserverIo\Appserver\Core\Server', + array( + 'initExtractors', + 'startContainers', + 'initProcessUser', + 'initContainers', + 'initProvisioners', + 'initFileSystem', + 'initSslCertificate', + 'getSystemLogger', + 'getSystemConfiguration' + ), + array($configuration), + '', + false + ); - // mock the servers start method + // mock the servers startContainers() and the initConstructors() method + $server->expects($this->once())->method('initExtractors'); + $server->expects($this->once())->method('initContainers'); $server->expects($this->once())->method('startContainers'); + $server->expects($this->once())->method('initProcessUser'); + $server->expects($this->once())->method('initProvisioners'); + $server->expects($this->once()) + ->method('getSystemLogger') + ->will($this->returnValue($mockLogger)); + $server->expects($this->once()) + ->method('getSystemConfiguration') + ->will($this->returnValue($mockSystemConfiguration)); // start the server instance $server->start(); - - // check that we found the configured container - $this->assertCount(1, $server->getContainers()); } /** @@ -126,13 +172,16 @@ public function testStart() */ public function testNewInstance() { + + // initialize the mock server + $mockServer = $this->getMockServer(array('initUmask','initFileSystem', 'initSslCertificate')); + + // create a new container thread instance $id = 1; $className = 'AppserverIo\Appserver\Core\Mock\MockContainerThread'; - $instance = $this->server->newInstance( + $instance = $mockServer->newInstance( $className, - array( - $this->server->getInitialContext(), \Mutex::create(false), $id - ) + array($mockServer->getInitialContext(), \Mutex::create(false), $id) ); $this->assertInstanceOf($className, $instance); } diff --git a/tests/_files/appserver.xml b/tests/_files/appserver.xml index 3f2d4f8ae..9921d9716 100644 --- a/tests/_files/appserver.xml +++ b/tests/_files/appserver.xml @@ -1,7 +1,9 @@ - /opt/appserver + + /opt/appserver +