From 8768c3ccc6f7a5972d82b1dfbc201ea3810ede88 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 30 Mar 2015 14:42:45 +0200 Subject: [PATCH 01/45] Refactor server/webserver dependencies --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7721a23e1..b0f9d17eb 100644 --- a/composer.json +++ b/composer.json @@ -75,4 +75,4 @@ "AppserverIo\\Appserver\\Meta\\Composer\\Script\\Setup::postInstall" ] } -} +} \ No newline at end of file From 72ecbd83367b3ebba8da14d500cfb5cc509ba98d Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 30 Mar 2015 14:49:08 +0200 Subject: [PATCH 02/45] Add bugfix to CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ed4dd111..f57dffe5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Bugfixes +* Fixed [#701](https://github.com/appserver-io/appserver/issues/701) - composer.phar is missing in Mac OS X/Linux build * Fixed [#682](https://github.com/appserver-io/appserver/issues/682) - Invalid output handling for fatal errors in Servlet-Engine * Fixed [#680](https://github.com/appserver-io/appserver/issues/680) - Multiple advices by different pointcuts are eliminating each other From 4c2451ab989f9cf67033a45dae111dca2cf31560 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 30 Mar 2015 15:03:25 +0200 Subject: [PATCH 03/45] Add UPGRADE-1.0.3.md file --- UPGRADE-1.0.3.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 UPGRADE-1.0.3.md diff --git a/UPGRADE-1.0.3.md b/UPGRADE-1.0.3.md new file mode 100644 index 000000000..85b624c15 --- /dev/null +++ b/UPGRADE-1.0.3.md @@ -0,0 +1,3 @@ +# Upgrade from 1.0.2 to 1.0.3 + +Updating from 1.0.2 to 1.0.3 doesn't have any impacts. For updates from [1.0.0](UPGRADE-1.0.1.md) or [1.0.1](UPGRADE-1.0.2.md) to 1.0.3 please read the apropriate UPGRADE-1.x.x files. From 1250638bc0ca879d90ccd873ee0f2a0ed32a9927 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Tue, 31 Mar 2015 11:54:13 +0200 Subject: [PATCH 04/45] configtest will return proper exit status now --- server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.php b/server.php index 566af8dfb..265aa55b7 100755 --- a/server.php +++ b/server.php @@ -130,7 +130,7 @@ if (array_key_exists($configTest, $arguments)) { echo $message; - exit; + exit(1); } throw new \Exception($message); } @@ -138,7 +138,7 @@ } elseif (array_key_exists($configTest, $arguments)) { echo "Syntax OK\n"; - exit; + exit(0); } // initialize the SimpleXMLElement with the content XML configuration file From 7c67134e886440ad48613700b915c546c9c85ad3 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Thu, 2 Apr 2015 16:04:28 +0200 Subject: [PATCH 05/45] removed usage of default pbc config --- .../Appserver/Core/DgClassLoader.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/DgClassLoader.php b/src/AppserverIo/Appserver/Core/DgClassLoader.php index 00adc6bf0..58b8d48d0 100644 --- a/src/AppserverIo/Appserver/Core/DgClassLoader.php +++ b/src/AppserverIo/Appserver/Core/DgClassLoader.php @@ -50,13 +50,6 @@ class DgClassLoader extends \Stackable implements ClassLoaderInterface { - /** - * Our default configuration file - * - * @const string CONFIG_FILE - */ - const CONFIG_FILE = 'pbc.conf.json'; - /** * The amount of structures we will generate per thread * @@ -92,19 +85,11 @@ class DgClassLoader extends \Stackable implements ClassLoaderInterface * Will check if there is content in the cache directory. * If not we will parse anew. * - * @param \AppserverIo\Doppelgaenger\Config|null $config An already existing config instance + * @param \AppserverIo\Doppelgaenger\Config $config An already existing config instance */ - public function __construct(Config $config = null) + public function __construct(Config $config) { - // query whether we've a configuration or not - if (is_null($config)) { - // if not we will get a context less configuration instance - $config = new Config(); - $config->load(APPSERVER_BP . DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . self::CONFIG_FILE); - - } - // set the configuration $this->config = $config; From 2564e980325d86b39ce6667798453600ee322dbe Mon Sep 17 00:00:00 2001 From: wick-ed Date: Thu, 2 Apr 2015 16:06:04 +0200 Subject: [PATCH 06/45] updated changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f57dffe5b..624e77ca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# Version 1.0.4 ++ ++## Bugfixes ++ ++* Fixed [#719](https://github.com/appserver-io/appserver/issues/719) - Around advice chain does break at certain size ++* Fixed [#721](https://github.com/appserver-io/appserver/issues/721) - Different order of Advices in pointcut.xml depending on type + +## Features + +* None + # Version 1.0.3 ## Bugfixes From 545301b3d5b94cad1368e3cce89ddf0a63bcc3f3 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Tue, 7 Apr 2015 10:08:37 +0200 Subject: [PATCH 07/45] Fixed #731 - Custom include paths in SplClassLoader not used --- CHANGELOG.md | 11 ++++++----- build.default.properties | 2 +- src/AppserverIo/Appserver/Core/SplClassLoader.php | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 624e77ca8..c5b512f80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ # Version 1.0.4 -+ -+## Bugfixes -+ -+* Fixed [#719](https://github.com/appserver-io/appserver/issues/719) - Around advice chain does break at certain size -+* Fixed [#721](https://github.com/appserver-io/appserver/issues/721) - Different order of Advices in pointcut.xml depending on type + +## Bugfixes + +* Fixed [#731](https://github.com/appserver-io/appserver/issues/731) - Custom include paths in SplClassLoader not used +* Fixed [#719](https://github.com/appserver-io/appserver/issues/719) - Around advice chain does break at certain size +* Fixed [#721](https://github.com/appserver-io/appserver/issues/721) - Different order of Advices in pointcut.xml depending on type ## Features diff --git a/build.default.properties b/build.default.properties index 642967afa..061efce2f 100644 --- a/build.default.properties +++ b/build.default.properties @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------------- # ---- Module Release Settings -------------------------------------------------- -release.version = 1.0.3 +release.version = 1.0.4 release.name = Iron Horse # ---- PHPCPD Settings ---------------------------------------------------------- diff --git a/src/AppserverIo/Appserver/Core/SplClassLoader.php b/src/AppserverIo/Appserver/Core/SplClassLoader.php index 2cf5795c2..94c03430d 100644 --- a/src/AppserverIo/Appserver/Core/SplClassLoader.php +++ b/src/AppserverIo/Appserver/Core/SplClassLoader.php @@ -111,7 +111,7 @@ public function __construct($classMap, $includePath, $namespace = null, $namespa } // set the include paths - $this->includePath = $paths; + $this->includePath = array_merge($this->includePath, $paths); } /** From dee6602ddfb970090ed427134a2407361ffc8446 Mon Sep 17 00:00:00 2001 From: Bernhard Wick Date: Tue, 7 Apr 2015 13:56:43 +0200 Subject: [PATCH 08/45] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b0f9d17eb..c17466dab 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ }, "config" : { "github-oauth" : { - "github.com" : "604a3b5943228e434a5b52c2ba3cf72286d30db9" + "github.com" : "6e24de467be8089a2fc49a3bd8d4f0dc795574ef" } }, "authors" : [{ @@ -75,4 +75,4 @@ "AppserverIo\\Appserver\\Meta\\Composer\\Script\\Setup::postInstall" ] } -} \ No newline at end of file +} From 4530d198fbf510d1f78f7a9271681db4b2d1aeda Mon Sep 17 00:00:00 2001 From: Bernhard Wick Date: Wed, 8 Apr 2015 09:37:36 +0200 Subject: [PATCH 09/45] Update composer.json --- composer.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/composer.json b/composer.json index c17466dab..1397901c8 100644 --- a/composer.json +++ b/composer.json @@ -40,11 +40,6 @@ ] } }, - "config" : { - "github-oauth" : { - "github.com" : "6e24de467be8089a2fc49a3bd8d4f0dc795574ef" - } - }, "authors" : [{ "name" : "Tim Wagner", "email" : "tw@appserver.io", From 926c353826f1cef90af69fa26d0f7219df57923d Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 13:54:19 +0200 Subject: [PATCH 10/45] Refactoring bootstrap process --- src/AppserverIo/Appserver/Core/Server.php | 128 ++++++++++++++-------- 1 file changed, 80 insertions(+), 48 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 90d8cdbde..1b41a6db2 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -31,6 +31,7 @@ use AppserverIo\Appserver\Core\Scanner\ScannerFactory; use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; use AppserverIo\Appserver\Core\Utilities\ContainerStateKeys; +use AppserverIo\Appserver\Core\Interfaces\ContainerInterface; /** * This is the main server class that starts the application server @@ -54,32 +55,32 @@ class Server protected $containers = array(); /** - * The system configuration. + * The registred extractors. * - * @var \AppserverIo\Configuration\Interfaces\NodeInterface + * @var array */ - protected $systemConfiguration; + protected $extractors = array(); /** - * The servers initial context instance. + * The registered provisioners. * - * @var \AppserverIo\Appserver\Application\Interfaces\ContextInterface + * @var array */ - protected $initialContext; + protected $provisioners = array(); /** - * The registred extractors. + * The system configuration. * - * @var array + * @var \AppserverIo\Configuration\Interfaces\NodeInterface */ - protected $extractors = array(); + protected $systemConfiguration; /** - * The registered provisioners. + * The servers initial context instance. * - * @var array + * @var \AppserverIo\Appserver\Application\Interfaces\ContextInterface */ - protected $provisioners = array(); + protected $initialContext; /** * Initializes the the server with the parsed configuration file. @@ -116,6 +117,12 @@ protected function init() $this->initLoggers(); // init the SSL certificate $this->initSslCertificate(); + // init the extractor + $this->initExtractors(); + // init the containers + $this->initContainers(); + // init the provisioners + $this->initProvisioners(); } /** @@ -251,17 +258,6 @@ protected function initExtractors() // create a new instance and add it to the internal array $this->addExtractor($this->newInstance($extractorNode->getType(), $params)); } - - // let the extractor extract the web applications - /** @var \AppserverIo\Appserver\Core\Interfaces\ExtractorInterface $extractor */ - foreach ($this->getExtractors() as $name => $extractor) { - - // deploy the found archives - $extractor->deployWebapps(); - - // log that the extractor has successfully been initialized and executed - $this->getSystemLogger()->debug(sprintf('Extractor %s successfully initialized and executed', $name)); - } } /** @@ -282,16 +278,6 @@ protected function initProvisioners() // create a new instance and add it to the internal array $this->addProvisioner($this->newInstance($provisionerNode->getType(), $params)); } - - // invoke the provisioners and provision the web applications - foreach ($this->getProvisioners() as $name => $provisioner) { - - // execute the provisioning steps - $provisioner->provision(); - - // log that the provisioner has successfully been initialized and executed - $this->getSystemLogger()->debug(sprintf('Provisioner %s successfully initialized and executed', $name)); - } } /** @@ -302,9 +288,6 @@ protected function initProvisioners() protected function initContainers() { - // initialize the array for the threads - $this->containers = array(); - // and initialize a container thread for each container foreach ($this->getSystemConfiguration()->getContainers() as $containerNode) { @@ -312,10 +295,22 @@ protected function initContainers() $params = array($this->getInitialContext(), $containerNode); // create and append the thread instance to the internal array - $this->containers[] = $this->newInstance($containerNode->getType(), $params); + $this->addContainer($this->newInstance($containerNode->getType(), $params)); } } + /** + * Adds the passed container to the server. + * + * @param \AppserverIo\Appserver\Core\Interfaces\ContainerInterface $container The container to add + * + * @return void + */ + public function addContainer(ContainerInterface $container) + { + $this->containers[] = $container; + } + /** * Returns the running container threads. * @@ -433,28 +428,25 @@ public function getProvisioners() public function start() { - // init the extractor - $this->initExtractors(); - - // init the containers - $this->initContainers(); - // log that the server will be started now $this->getSystemLogger()->info( sprintf( - 'Server successfully started in basedirectory %s ', + 'Now starting Server in basedirectory %s ', $this->getSystemConfiguration()->getBaseDirectory() ) ); + // extract the application archives + $this->extract(); + // start the container threads $this->startContainers(); // Switch to the configured user (if any) - $this->initProcessUser(); + $this->switchProcessUser(); - // init the provisioner - $this->initProvisioners(); + // provision the applications + $this->provision(); } /** @@ -535,7 +527,7 @@ public function startContainers() * * @return void */ - protected function initProcessUser() + protected function switchProcessUser() { // if we're on a OS (not Windows) that supports POSIX we have // to change the configured user/group for security reasons. @@ -626,6 +618,46 @@ protected function initProcessUser() ); } + /** + * Provision the applications. + * + * @return void + */ + protected function provision() + { + + // invoke the provisioners and provision the web applications + /** @var \AppserverIo\Appserver\Core\Interfaces\ProvisionerInterface $provisioner */ + foreach ($this->getProvisioners() as $name => $provisioner) { + + // execute the provisioning steps + $provisioner->provision(); + + // log that the provisioner has successfully been initialized and executed + $this->getSystemLogger()->info(sprintf('Provisioner %s successfully initialized and executed', $name)); + } + } + + /** + * Extracts the application archives to the configured document root. + * + * @return void + */ + protected function extract() + { + + // let the extractor extract the web applications + /** @var \AppserverIo\Appserver\Core\Interfaces\ExtractorInterface $extractor */ + foreach ($this->getExtractors() as $name => $extractor) { + + // deploy the found archives + $extractor->deployWebapps(); + + // log that the extractor has successfully been initialized and executed + $this->getSystemLogger()->debug(sprintf('Extractor %s successfully initialized and executed', $name)); + } + } + /** * Returns a new instance of the passed class name. * From 7e77a89703e2854af24bd193b92a31b18a6d88d5 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 16:55:03 +0200 Subject: [PATCH 11/45] Fixed #725 - no Datasources in Singleton SessionBean --- phpunit.xml | 1 + server.php | 1 + .../Appserver/Application/Application.php | 3 ++ .../Application/ApplicationFactory.php | 6 --- .../Interfaces/ContextInterface.php | 7 ---- .../Core/AbstractContainerThread.php | 25 ------------ .../Appserver/Core/AbstractContextThread.php | 2 +- .../Appserver/Core/Api/Node/AppserverNode.php | 3 +- .../Core/Api/Node/InitialContextNode.php | 22 +---------- .../Appserver/Core/InitialContext.php | 26 ------------- .../Core/Provisioning/CreateDatabaseStep.php | 4 +- src/AppserverIo/Appserver/Core/Server.php | 37 ++++++++++++++---- .../Appserver/Application/ApplicationTest.php | 1 - .../Appserver/Core/InitialContextTest.php | 10 ----- .../AppserverIo/Appserver/Core/ServerTest.php | 38 ++++++------------- tests/_files/appserver.xml | 4 +- tests/_files/appserver_initial_context.xml | 1 - var/scripts/bootstrap.php | 14 ++++++- 18 files changed, 66 insertions(+), 139 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index d9e30cec8..7b20831ef 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -22,5 +22,6 @@ + \ No newline at end of file diff --git a/server.php b/server.php index 265aa55b7..76a2f6abc 100755 --- a/server.php +++ b/server.php @@ -56,6 +56,7 @@ // define a all constants appserver base directory define('APPSERVER_BP', __DIR__); + // define install flag for setup mode install to check define( 'IS_INSTALLED_FILE', diff --git a/src/AppserverIo/Appserver/Application/Application.php b/src/AppserverIo/Appserver/Application/Application.php index e0867cb8a..4ee379ffa 100644 --- a/src/AppserverIo/Appserver/Application/Application.php +++ b/src/AppserverIo/Appserver/Application/Application.php @@ -587,6 +587,9 @@ public function connect() public function registerClassLoaders() { + // register the default autoloader + require SERVER_AUTOLOADER; + // initialize the registered managers /** @var \AppserverIo\Appserver\Core\Interfaces\ClassLoaderInterface $classLoader */ foreach ($this->getClassLoaders() as $classLoader) { diff --git a/src/AppserverIo/Appserver/Application/ApplicationFactory.php b/src/AppserverIo/Appserver/Application/ApplicationFactory.php index 43c90add9..18db42bea 100644 --- a/src/AppserverIo/Appserver/Application/ApplicationFactory.php +++ b/src/AppserverIo/Appserver/Application/ApplicationFactory.php @@ -97,12 +97,6 @@ public static function visit(ContainerInterface $container, ContextNode $context $appService->createTmpFolders($application); $appService->cleanUpFolders($application); - // add the default class loader - $application->addClassLoader( - $initialContext->getClassLoader(), - $initialContext->getSystemConfiguration()->getInitialContext()->getClassLoader() - ); - // add the configured class loaders /** @var \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode $classLoader */ foreach ($context->getClassLoaders() as $classLoader) { diff --git a/src/AppserverIo/Appserver/Application/Interfaces/ContextInterface.php b/src/AppserverIo/Appserver/Application/Interfaces/ContextInterface.php index a67764109..5b5b3ec96 100644 --- a/src/AppserverIo/Appserver/Application/Interfaces/ContextInterface.php +++ b/src/AppserverIo/Appserver/Application/Interfaces/ContextInterface.php @@ -53,13 +53,6 @@ public function newInstance($className, array $args = array()); */ public function newService($className); - /** - * Returns the default class loader. - * - * @return object The class loader used - */ - public function getClassLoader(); - /** * Gets the logger by given name * diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index b96d12f10..50874cadf 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -127,36 +127,11 @@ public function main() // initialize the container state $this->containerState = ContainerStateKeys::get(ContainerStateKeys::INITIALIZATION_SUCCESSFUL); - // define webservers base dir - define( - 'SERVER_BASEDIR', - $this->getInitialContext()->getSystemConfiguration()->getBaseDirectory() . DIRECTORY_SEPARATOR - ); - - // check if we've the old or the new directory structure - if (file_exists(SERVER_BASEDIR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) { - $autoloaderFile = SERVER_BASEDIR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; - } else { - // this is the old directory structure - $autoloaderFile = SERVER_BASEDIR . 'app' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; - } - - // define the autoloader file - define('SERVER_AUTOLOADER', $autoloaderFile); - - // deploy and initialize the applications for this container - $deployment = $this->getDeployment(); - $deployment->injectContainer($this); - $deployment->deploy(); - // initialize the profile logger and the thread context if ($profileLogger = $this->getInitialContext()->getLogger(LoggerUtils::PROFILE)) { $profileLogger->appendThreadContext($this->getContainerNode()->getName()); } - // deployment has been successful - $this->containerState = ContainerStateKeys::get(ContainerStateKeys::DEPLOYMENT_SUCCESSFUL); - // setup configurations $serverConfigurations = array(); foreach ($this->getContainerNode()->getServers() as $serverNode) { diff --git a/src/AppserverIo/Appserver/Core/AbstractContextThread.php b/src/AppserverIo/Appserver/Core/AbstractContextThread.php index 6d202ae96..e0c7ad9f8 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContextThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContextThread.php @@ -65,7 +65,7 @@ public function __construct($initialContext) public function run() { // register the class loader again, because in a Thread the context has been lost maybe - $this->getInitialContext()->getClassLoader()->register(true); + require SERVER_AUTOLOADER; // call the parent run method to start the thread parent::run(); diff --git a/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php b/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php index da3afc810..4b474253f 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php @@ -141,11 +141,10 @@ protected function initDefaultInitialContext() // initialize the configuration values for the initial context $description = new DescriptionNode(new NodeValue('The initial context configuration.')); - $classLoader = new ClassLoaderNode('SplClassLoader', 'ClassLoaderInterface', 'AppserverIo\Appserver\Core\SplClassLoader'); $storage = new StorageNode('AppserverIo\Storage\StackableStorage'); // set the default initial context configuration - $this->initialContext = new InitialContextNode('AppserverIo\Appserver\Core\InitialContext', $description, $classLoader, $storage); + $this->initialContext = new InitialContextNode('AppserverIo\Appserver\Core\InitialContext', $description, $storage); } /** diff --git a/src/AppserverIo/Appserver/Core/Api/Node/InitialContextNode.php b/src/AppserverIo/Appserver/Core/Api/Node/InitialContextNode.php index fb9b18a28..969e5a24e 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/InitialContextNode.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/InitialContextNode.php @@ -48,14 +48,6 @@ class InitialContextNode extends AbstractNode */ protected $description; - /** - * Node containing information about the class loader used by the initial context. - * - * @var \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode - * @AS\Mapping(nodeName="classLoader", nodeType="AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode") - */ - protected $classLoader; - /** * Node containing information about the storage implementation used by the inital context. * @@ -69,10 +61,9 @@ class InitialContextNode extends AbstractNode * * @param string $type The initial context type * @param \AppserverIo\Appserver\Core\Api\Node\DescriptionNode $description A short description - * @param \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode $classLoader The default class loader configuration * @param \AppserverIo\Appserver\Core\Api\Node\StorageNode $storage The default storage configuration */ - public function __construct($type = '', DescriptionNode $description = null, ClassLoaderNode $classLoader = null, StorageNode $storage = null) + public function __construct($type = '', DescriptionNode $description = null, StorageNode $storage = null) { // initialize the UUID @@ -81,7 +72,6 @@ public function __construct($type = '', DescriptionNode $description = null, Cla // set the data $this->type = $type; $this->description = $description; - $this->classLoader = $classLoader; $this->storage = $storage; } @@ -116,16 +106,6 @@ public function getDescription() return $this->description; } - /** - * Returns the class loader configuration information. - * - * @return \AppserverIo\Appserver\Core\Api\Node\ClassLoaderNode The node with the class loader information - */ - public function getClassLoader() - { - return $this->classLoader; - } - /** * Returns the storage configuration information. * diff --git a/src/AppserverIo/Appserver/Core/InitialContext.php b/src/AppserverIo/Appserver/Core/InitialContext.php index 5f41aec6b..cbef17750 100644 --- a/src/AppserverIo/Appserver/Core/InitialContext.php +++ b/src/AppserverIo/Appserver/Core/InitialContext.php @@ -84,10 +84,6 @@ public function __construct(SystemConfigurationInterface $systemConfiguration) // add the storage to the initial context $this->setStorage($storage); - // initialize the default class loader instance - $classLoaderType = $initialContextNode->getClassLoader()->getType(); - $this->setClassLoader($classLoaderType::factory()); - // attach the system configuration to the initial context $this->setSystemConfiguration($systemConfiguration); } @@ -114,28 +110,6 @@ public function getStorage() return $this->storage; } - /** - * Set's the initial context's class loader. - * - * @param \AppserverIo\Appserver\Core\Interfaces\ClassLoaderInterface $classLoader The class loader used - * - * @return void - */ - public function setClassLoader(ClassLoaderInterface $classLoader) - { - $this->classLoader = $classLoader; - } - - /** - * Returns the initial context's class loader. - * - * @return \AppserverIo\Appserver\Core\SplClassLoader The class loader used - */ - public function getClassLoader() - { - return $this->classLoader; - } - /** * Adds the system configuration to the initial context. * diff --git a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php index 77c9966e9..d1fd55a2e 100644 --- a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php +++ b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php @@ -100,8 +100,8 @@ public function execute() // load the database connection parameters $connectionParameters = $this->getConnectionParameters(); - // register the class loader - $this->getInitialContext()->getClassLoader()->register(true, true); + // register the class loader again, because in a Thread the context has been lost maybe + require SERVER_AUTOLOADER; // initialize and load the entity manager and the schema tool $metadataConfiguration = Setup::createAnnotationMetadataConfiguration($absolutePaths, true); diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 1b41a6db2..6500a0e4c 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -20,18 +20,18 @@ namespace AppserverIo\Appserver\Core; -use AppserverIo\Appserver\Core\Interfaces\SystemConfigurationInterface; -use AppserverIo\Appserver\Core\Scanner\HeartbeatScanner; use AppserverIo\Logger\LoggerUtils; -use AppserverIo\Configuration\Interfaces\ConfigurationInterface; -use AppserverIo\Appserver\Core\Interfaces\ProvisionerInterface; -use AppserverIo\Appserver\Core\Interfaces\ExtractorInterface; use AppserverIo\Appserver\Core\InitialContext; use AppserverIo\Appserver\Core\Api\Node\AppserverNode; use AppserverIo\Appserver\Core\Scanner\ScannerFactory; +use AppserverIo\Appserver\Core\Scanner\HeartbeatScanner; use AppserverIo\Appserver\Core\Utilities\DirectoryKeys; use AppserverIo\Appserver\Core\Utilities\ContainerStateKeys; +use AppserverIo\Appserver\Core\Interfaces\ExtractorInterface; use AppserverIo\Appserver\Core\Interfaces\ContainerInterface; +use AppserverIo\Appserver\Core\Interfaces\ProvisionerInterface; +use AppserverIo\Appserver\Core\Interfaces\SystemConfigurationInterface; +use AppserverIo\Configuration\Interfaces\ConfigurationInterface; /** * This is the main server class that starts the application server @@ -106,7 +106,6 @@ public function __construct(ConfigurationInterface $configuration) */ protected function init() { - // init the umask to use creating files/directories $this->initUmask(); // init initial context @@ -447,6 +446,9 @@ public function start() // provision the applications $this->provision(); + + // deploy the applications + $this->deploy(); } /** @@ -501,7 +503,7 @@ public function watch() * * @return void */ - public function startContainers() + protected function startContainers() { // start the container threads @@ -618,6 +620,27 @@ protected function switchProcessUser() ); } + /** + * Deploys the applications for each container, found in the containers + * configured document root. + * + * @return void + */ + protected function deploy() + { + + // deploy the applications for each container + foreach ($this->getContainers() as $container) { + + // load the containers deployment + $deployment = $container->getDeployment(); + $deployment->injectContainer($container); + + // deploy and initialize the container's applications + $deployment->deploy(); + } + } + /** * Provision the applications. * diff --git a/tests/AppserverIo/Appserver/Application/ApplicationTest.php b/tests/AppserverIo/Appserver/Application/ApplicationTest.php index 9b2425399..3e4359d0c 100644 --- a/tests/AppserverIo/Appserver/Application/ApplicationTest.php +++ b/tests/AppserverIo/Appserver/Application/ApplicationTest.php @@ -161,7 +161,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function setUp() { - // initialize the application instance $this->application = new Application(); diff --git a/tests/AppserverIo/Appserver/Core/InitialContextTest.php b/tests/AppserverIo/Appserver/Core/InitialContextTest.php index 0b7a5f465..f22ef00fe 100644 --- a/tests/AppserverIo/Appserver/Core/InitialContextTest.php +++ b/tests/AppserverIo/Appserver/Core/InitialContextTest.php @@ -58,16 +58,6 @@ public function testGetStorage() $this->assertInstanceOf('AppserverIo\Storage\StorageInterface', $this->initialContext->getStorage()); } - /** - * Tests the if the class loader has been initialized successfully. - * - * @return void - */ - public function testGetClassLoader() - { - $this->assertInstanceOf('AppserverIo\Appserver\Core\SplClassLoader', $this->initialContext->getClassLoader()); - } - /** * Tests the if the attribute getter/setter works with a simple data type. * diff --git a/tests/AppserverIo/Appserver/Core/ServerTest.php b/tests/AppserverIo/Appserver/Core/ServerTest.php index 6a61fc70e..3080da99e 100644 --- a/tests/AppserverIo/Appserver/Core/ServerTest.php +++ b/tests/AppserverIo/Appserver/Core/ServerTest.php @@ -20,8 +20,8 @@ namespace AppserverIo\Appserver\Core; use AppserverIo\Configuration\Configuration; -use AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode; use AppserverIo\Appserver\Core\Api\Node\NodeValue; +use AppserverIo\Appserver\Core\Api\Node\BaseDirectoryNode; /** * Test for the server implementation. @@ -118,18 +118,6 @@ public function testGetSystemConfiguration() public function testStart() { - // 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); - // initialize the mock logger $mockLogger = $this->getMockLogger(); @@ -143,27 +131,25 @@ public function testStart() $server = $this->getMock( 'AppserverIo\Appserver\Core\Server', array( - 'initExtractors', - 'startContainers', - 'initProcessUser', - 'initContainers', - 'initProvisioners', - 'initFileSystem', - 'initSslCertificate', 'getSystemLogger', - 'getSystemConfiguration' + 'getSystemConfiguration', + 'switchProcessUser', + 'startContainers', + 'provision', + 'extract', + 'deploy' ), - array($configuration), + array(), '', false ); // 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('switchProcessUser'); + $server->expects($this->once())->method('provision'); + $server->expects($this->once())->method('extract'); + $server->expects($this->once())->method('deploy'); $server->expects($this->once()) ->method('getSystemLogger') ->will($this->returnValue($mockLogger)); diff --git a/tests/_files/appserver.xml b/tests/_files/appserver.xml index 2de9b408b..f8e1ce274 100644 --- a/tests/_files/appserver.xml +++ b/tests/_files/appserver.xml @@ -15,9 +15,7 @@ - - + diff --git a/tests/_files/appserver_initial_context.xml b/tests/_files/appserver_initial_context.xml index e44210a13..5bd19e78b 100644 --- a/tests/_files/appserver_initial_context.xml +++ b/tests/_files/appserver_initial_context.xml @@ -1,5 +1,4 @@ - \ No newline at end of file diff --git a/var/scripts/bootstrap.php b/var/scripts/bootstrap.php index 53b374892..a8a1a6317 100644 --- a/var/scripts/bootstrap.php +++ b/var/scripts/bootstrap.php @@ -32,4 +32,16 @@ // set the new include path set_include_path(get_include_path() . PATH_SEPARATOR . implode(PATH_SEPARATOR, $paths)); -require APPSERVER_BP . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; +// define application servers base dir +define('SERVER_BASEDIR', APPSERVER_BP . DIRECTORY_SEPARATOR); + +// query whether we've a composer autoloader defined or not +if (!file_exists($autoloaderFile = SERVER_BASEDIR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) { + throw new \Exception(sprintf('Can\' find default autoloader %s', $autoloaderFile)); +} + +// define the autoloader file +define('SERVER_AUTOLOADER', $autoloaderFile); + +// initialize the composer autoloader +require $autoloaderFile; From cef451b3df1ea1550dbee835a36d5a706f184a1b Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 17:01:00 +0200 Subject: [PATCH 12/45] Remove unnessesary container state key --- .../Appserver/Core/Utilities/ContainerStateKeys.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php b/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php index a82ae7221..e4d2b566a 100644 --- a/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php +++ b/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php @@ -53,19 +53,12 @@ class ContainerStateKeys */ const INITIALIZATION_SUCCESSFUL = 2; - /** - * Deployment has been successfull. - * - * @var integer - */ - const DEPLOYMENT_SUCCESSFUL = 3; - /** * Servers has been started successful. * * @var integer */ - const SERVERS_STARTED_SUCCESSFUL = 4; + const SERVERS_STARTED_SUCCESSFUL = 3; /** * The actual container state. @@ -125,7 +118,6 @@ public static function getContainerStates() return array( ContainerStateKeys::WAITING_FOR_INITIALIZATION, ContainerStateKeys::INITIALIZATION_SUCCESSFUL, - ContainerStateKeys::DEPLOYMENT_SUCCESSFUL, ContainerStateKeys::SERVERS_STARTED_SUCCESSFUL ); } From fff64063f7b5a40d91f9364305b8c5e6bfd0f017 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 19:08:41 +0200 Subject: [PATCH 13/45] Datasources will now be deployed, instead of provisioned --- .../Core/AbstractContainerThread.php | 7 ++ .../Appserver/Core/AbstractDeployment.php | 40 +++++++++++ .../Appserver/Core/Api/Node/AppserverNode.php | 5 +- .../Appserver/Core/DatasourceProvisioner.php | 71 ------------------- .../Appserver/Core/GenericDeployment.php | 45 ++++++++++++ src/AppserverIo/Appserver/Core/Server.php | 24 ------- .../AppserverIo/Appserver/Core/ServerTest.php | 4 +- 7 files changed, 94 insertions(+), 102 deletions(-) delete mode 100644 src/AppserverIo/Appserver/Core/DatasourceProvisioner.php diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index 50874cadf..b3b7ddd13 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -124,6 +124,13 @@ public function main() // initialize instance that contains the applications $this->applications = new GenericStackable(); + // load the containers deployment + $deployment = $this->getDeployment(); + $deployment->injectContainer($this); + + // deploy and initialize the container's applications + $deployment->deploy(); + // initialize the container state $this->containerState = ContainerStateKeys::get(ContainerStateKeys::INITIALIZATION_SUCCESSFUL); diff --git a/src/AppserverIo/Appserver/Core/AbstractDeployment.php b/src/AppserverIo/Appserver/Core/AbstractDeployment.php index f294ecb22..d86147181 100644 --- a/src/AppserverIo/Appserver/Core/AbstractDeployment.php +++ b/src/AppserverIo/Appserver/Core/AbstractDeployment.php @@ -50,6 +50,20 @@ abstract class AbstractDeployment implements DeploymentInterface */ protected $deploymentService; + /** + * The configuration service instance. + * + * @var \AppserverIo\Appserver\Core\Api\ConfigurationService + */ + protected $configurationService; + + /** + * The datasource service instance. + * + * @var \AppserverIo\Appserver\Core\Api\DatasourceService + */ + protected $datasourceService; + /** * Injects the container instance. * @@ -85,6 +99,32 @@ public function getDeploymentService() return $this->deploymentService; } + /** + * Returns the configuration service instance. + * + * @return \AppserverIo\Appserver\Core\Api\ConfigurationService The configuration service instance + */ + public function getConfigurationService() + { + if ($this->configurationService == null) { + $this->configurationService = $this->newService('AppserverIo\Appserver\Core\Api\ConfigurationService'); + } + return $this->configurationService; + } + + /** + * Returns the datasource service instance. + * + * @return \AppserverIo\Appserver\Core\Api\DatasourceService The datasource service instance + */ + public function getDatasourceService() + { + if ($this->datasourceService == null) { + $this->datasourceService = $this->newService('AppserverIo\Appserver\Core\Api\DatasourceService'); + } + return $this->datasourceService; + } + /** * Returns the initial context instance. * diff --git a/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php b/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php index 4b474253f..e0d75647f 100644 --- a/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php +++ b/src/AppserverIo/Appserver/Core/Api/Node/AppserverNode.php @@ -204,8 +204,7 @@ protected function initDefaultExtractors() } /** - * Initializes the default provisioners for database and - * application database relation. + * Initializes the default provisioners. * * @return void */ @@ -213,11 +212,9 @@ protected function initDefaultProvisioners() { // initialize the provisioners - $datasourceProvisioner = new ProvisionerNode('datasource', 'AppserverIo\Appserver\Core\DatasourceProvisioner'); $standardProvisioner = new ProvisionerNode('standard', 'AppserverIo\Appserver\Core\StandardProvisioner'); // add the provisioners to the appserver node - $this->provisioners[$datasourceProvisioner->getPrimaryKey()] = $datasourceProvisioner; $this->provisioners[$standardProvisioner->getPrimaryKey()] = $standardProvisioner; } diff --git a/src/AppserverIo/Appserver/Core/DatasourceProvisioner.php b/src/AppserverIo/Appserver/Core/DatasourceProvisioner.php deleted file mode 100644 index 36af7e02a..000000000 --- a/src/AppserverIo/Appserver/Core/DatasourceProvisioner.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright 2015 TechDivision GmbH - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link https://github.com/appserver-io/appserver - * @link http://www.appserver.io - */ - -namespace AppserverIo\Appserver\Core; - -use AppserverIo\Appserver\Core\Api\ConfigurationService; - -/** - * Standard provisioning functionality. - * - * @author Tim Wagner - * @copyright 2015 TechDivision GmbH - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - * @link https://github.com/appserver-io/appserver - * @link http://www.appserver.io - */ -class DatasourceProvisioner extends AbstractProvisioner -{ - - /** - * Provision all datasources recursively found in the web application directory. - * - * @return void - */ - public function provision() - { - - // check if deploy dir exists - if (is_dir($directory = $this->getWebappsDir())) { - // load the datasource files - $datasourceFiles = $this->getService()->globDir($directory . DIRECTORY_SEPARATOR . '*-ds.xml'); - // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration - $configurationService = new ConfigurationService($this->getInitialContext()); - foreach ($datasourceFiles as $datasourceFile) { - // validate the file, but skip it if validation fails - if (!$configurationService->validateFile($datasourceFile)) { - $errorMessages = $configurationService->getErrorMessages(); - $systemLogger = $this->getInitialContext()->getSystemLogger(); - $systemLogger->error(reset($errorMessages)); - $systemLogger->critical(sprintf('Will skip reading configuration in %s, datasources might be missing.', $datasourceFile)); - continue; - } - - // load the database configuration - $datasourceNodes = $this->getService()->initFromFile($datasourceFile); - - // store the datasource in the system configuration - foreach ($datasourceNodes as $datasourceNode) { - $this->getService()->persist($datasourceNode); - } - } - } - } -} diff --git a/src/AppserverIo/Appserver/Core/GenericDeployment.php b/src/AppserverIo/Appserver/Core/GenericDeployment.php index c32b231ec..8b0792f7f 100644 --- a/src/AppserverIo/Appserver/Core/GenericDeployment.php +++ b/src/AppserverIo/Appserver/Core/GenericDeployment.php @@ -39,6 +39,51 @@ class GenericDeployment extends AbstractDeployment * @see \AppserverIo\Psr\Deployment\DeploymentInterface::deploy() */ public function deploy() + { + $this->deployDatasources(); + $this->deployApplications(); + } + + /** + * Deploys the available datasources. + * + * @return void + */ + protected function deployDatasources() + { + + // check if deploy dir exists + if (is_dir($directory = $this->getDeploymentService()->getWebappsDir())) { + // load the datasource files + $datasourceFiles = $this->getDeploymentService()->globDir($directory . DIRECTORY_SEPARATOR . '*-ds.xml'); + // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration + foreach ($datasourceFiles as $datasourceFile) { + // validate the file, but skip it if validation fails + if ($this->getConfigurationService()->validateFile($datasourceFile) === false) { + $errorMessages = $configurationService->getErrorMessages(); + $systemLogger = $this->getInitialContext()->getSystemLogger(); + $systemLogger->error(reset($errorMessages)); + $systemLogger->critical(sprintf('Will skip reading configuration in %s, datasources might be missing.', $datasourceFile)); + continue; + } + + // load the database configuration + $datasourceNodes = $this->getDatasourceService()->initFromFile($datasourceFile); + + // store the datasource in the system configuration + foreach ($datasourceNodes as $datasourceNode) { + $this->getDatasourceService()->persist($datasourceNode); + } + } + } + } + + /** + * Deploys the available applications. + * + * @return void + */ + protected function deployApplications() { // load the container and initial context instance diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 6500a0e4c..5a4f53f07 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -446,9 +446,6 @@ public function start() // provision the applications $this->provision(); - - // deploy the applications - $this->deploy(); } /** @@ -620,27 +617,6 @@ protected function switchProcessUser() ); } - /** - * Deploys the applications for each container, found in the containers - * configured document root. - * - * @return void - */ - protected function deploy() - { - - // deploy the applications for each container - foreach ($this->getContainers() as $container) { - - // load the containers deployment - $deployment = $container->getDeployment(); - $deployment->injectContainer($container); - - // deploy and initialize the container's applications - $deployment->deploy(); - } - } - /** * Provision the applications. * diff --git a/tests/AppserverIo/Appserver/Core/ServerTest.php b/tests/AppserverIo/Appserver/Core/ServerTest.php index 3080da99e..41cb229ce 100644 --- a/tests/AppserverIo/Appserver/Core/ServerTest.php +++ b/tests/AppserverIo/Appserver/Core/ServerTest.php @@ -136,8 +136,7 @@ public function testStart() 'switchProcessUser', 'startContainers', 'provision', - 'extract', - 'deploy' + 'extract' ), array(), '', @@ -149,7 +148,6 @@ public function testStart() $server->expects($this->once())->method('switchProcessUser'); $server->expects($this->once())->method('provision'); $server->expects($this->once())->method('extract'); - $server->expects($this->once())->method('deploy'); $server->expects($this->once()) ->method('getSystemLogger') ->will($this->returnValue($mockLogger)); From de8d9074245141341efe404f14368c06b098c8b2 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 19:13:34 +0200 Subject: [PATCH 14/45] Reset container state keys in abstract container --- .../Appserver/Core/AbstractContainerThread.php | 7 +++++-- .../Appserver/Core/Utilities/ContainerStateKeys.php | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index b3b7ddd13..6efdbc1ba 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -121,6 +121,9 @@ public function main() $logDir->bind($name, $logger); } + // initialize the container state + $this->containerState = ContainerStateKeys::get(ContainerStateKeys::INITIALIZATION_SUCCESSFUL); + // initialize instance that contains the applications $this->applications = new GenericStackable(); @@ -131,8 +134,8 @@ public function main() // deploy and initialize the container's applications $deployment->deploy(); - // initialize the container state - $this->containerState = ContainerStateKeys::get(ContainerStateKeys::INITIALIZATION_SUCCESSFUL); + // deployment has been successful + $this->containerState = ContainerStateKeys::get(ContainerStateKeys::DEPLOYMENT_SUCCESSFUL); // initialize the profile logger and the thread context if ($profileLogger = $this->getInitialContext()->getLogger(LoggerUtils::PROFILE)) { diff --git a/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php b/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php index e4d2b566a..a82ae7221 100644 --- a/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php +++ b/src/AppserverIo/Appserver/Core/Utilities/ContainerStateKeys.php @@ -53,12 +53,19 @@ class ContainerStateKeys */ const INITIALIZATION_SUCCESSFUL = 2; + /** + * Deployment has been successfull. + * + * @var integer + */ + const DEPLOYMENT_SUCCESSFUL = 3; + /** * Servers has been started successful. * * @var integer */ - const SERVERS_STARTED_SUCCESSFUL = 3; + const SERVERS_STARTED_SUCCESSFUL = 4; /** * The actual container state. @@ -118,6 +125,7 @@ public static function getContainerStates() return array( ContainerStateKeys::WAITING_FOR_INITIALIZATION, ContainerStateKeys::INITIALIZATION_SUCCESSFUL, + ContainerStateKeys::DEPLOYMENT_SUCCESSFUL, ContainerStateKeys::SERVERS_STARTED_SUCCESSFUL ); } From aa11ae6dee8784c68800ca8e4b04a90c924e4179 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 9 Apr 2015 19:22:43 +0200 Subject: [PATCH 15/45] Update CHANGELOG.md with latest bugfix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b512f80..ad6113e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Bugfixes +* Fixed [#725](https://github.com/appserver-io/appserver/issues/725) - no Datasources in Singleton SessionBean * Fixed [#731](https://github.com/appserver-io/appserver/issues/731) - Custom include paths in SplClassLoader not used * Fixed [#719](https://github.com/appserver-io/appserver/issues/719) - Around advice chain does break at certain size * Fixed [#721](https://github.com/appserver-io/appserver/issues/721) - Different order of Advices in pointcut.xml depending on type From 0ad984e4709c6f1c6ada37e40fefc2a05da40346 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Fri, 10 Apr 2015 15:31:14 +0200 Subject: [PATCH 16/45] skipped some tests as their \Stackable usage makes problems --- .../Functional/AspectContainer/AspectManagerTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/AppserverIo/Appserver/Functional/AspectContainer/AspectManagerTest.php b/tests/AppserverIo/Appserver/Functional/AspectContainer/AspectManagerTest.php index 571647662..3e01a3351 100644 --- a/tests/AppserverIo/Appserver/Functional/AspectContainer/AspectManagerTest.php +++ b/tests/AppserverIo/Appserver/Functional/AspectContainer/AspectManagerTest.php @@ -141,6 +141,8 @@ public function testXmlGetsTakenFromAllDirectories() */ public function testXmlAllowsForMultiAdviceOfDifferentAspect() { + $this->markTestSkipped('Strange behaviour related to \Stackable usage. Skipped until an alternative has been found.'); + $configPath = $this->getMockWebappPath() . DIRECTORY_SEPARATOR . 'WEB-INF' . DIRECTORY_SEPARATOR .'pointcuts.xml'; $mockApplication = $this->getSpecificConfigMockApplication($configPath); @@ -161,6 +163,8 @@ public function testXmlAllowsForMultiAdviceOfDifferentAspect() */ public function testXmlAllowsForMultiAdviceOfSameAspect() { + $this->markTestSkipped('Strange behaviour related to \Stackable usage. Skipped until an alternative has been found.'); + $configPath = $this->getMockWebappPath() . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR .'pointcuts.xml'; $mockApplication = $this->getSpecificConfigMockApplication($configPath); @@ -181,6 +185,8 @@ public function testXmlAllowsForMultiAdviceOfSameAspect() */ public function testXmlAllowsForMultiPointcut() { + $this->markTestSkipped('Strange behaviour related to \Stackable usage. Skipped until an alternative has been found.'); + $configPath = $this->getMockWebappPath() . DIRECTORY_SEPARATOR . 'META-INF' . DIRECTORY_SEPARATOR .'pointcuts.xml'; $mockApplication = $this->getSpecificConfigMockApplication($configPath); From 8fe9008a7ac86248c6302dae4eb9825b6c683850 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Fri, 17 Apr 2015 13:56:47 +0200 Subject: [PATCH 17/45] created upgrade instructions --- UPGRADE-1.0.4.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 UPGRADE-1.0.4.md diff --git a/UPGRADE-1.0.4.md b/UPGRADE-1.0.4.md new file mode 100644 index 000000000..992a11e8f --- /dev/null +++ b/UPGRADE-1.0.4.md @@ -0,0 +1,3 @@ +# Upgrade from 1.0.3 to 1.0.4 + +Updating from 1.0.3 to 1.0.4 doesn't have any impacts. Please read the apropriate UPGRADE-1.x.x files for updates from older versions to 1.0.3. From 534bba41bcdb7ee2f462072fd7408277968fd7b0 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 20 Apr 2015 19:25:04 +0200 Subject: [PATCH 18/45] Fixed #760 - Asynchronous Deployment of Applications --- .../etc/appserver/appserver.xml.phtml | 1 + .../Core/AbstractContainerThread.php | 7 - src/AppserverIo/Appserver/Core/Server.php | 30 ++- .../Appserver/MessageQueue/MessageQueue.php | 243 ++++++++++++++++-- .../MessageQueue/MessageQueueModule.php | 153 +---------- .../MessageQueue/MessageQueueValve.php | 80 ++++++ .../Appserver/MessageQueue/QueueLocator.php | 24 +- .../Appserver/MessageQueue/QueueManager.php | 98 +++++-- .../MessageQueue/QueueManagerFactory.php | 6 +- .../Appserver/MessageQueue/QueueWorker.php | 112 +++++--- .../ServletEngine/RequestHandler.php | 4 +- 11 files changed, 511 insertions(+), 247 deletions(-) create mode 100644 src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php diff --git a/resources/templates/etc/appserver/appserver.xml.phtml b/resources/templates/etc/appserver/appserver.xml.phtml index 1ec5ddc83..76d575785 100644 --- a/resources/templates/etc/appserver/appserver.xml.phtml +++ b/resources/templates/etc/appserver/appserver.xml.phtml @@ -75,6 +75,7 @@ use AppserverIo\Appserver\Meta\Composer\Script\SetupKeys; + webapps index.mq 64 5 diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index 6efdbc1ba..534b819b0 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -127,13 +127,6 @@ public function main() // initialize instance that contains the applications $this->applications = new GenericStackable(); - // load the containers deployment - $deployment = $this->getDeployment(); - $deployment->injectContainer($this); - - // deploy and initialize the container's applications - $deployment->deploy(); - // deployment has been successful $this->containerState = ContainerStateKeys::get(ContainerStateKeys::DEPLOYMENT_SUCCESSFUL); diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 5a4f53f07..7608f183a 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -435,15 +435,18 @@ public function start() ) ); - // extract the application archives - $this->extract(); - // start the container threads $this->startContainers(); // Switch to the configured user (if any) $this->switchProcessUser(); + // extract the application archives + $this->extract(); + + // deploy the applications + $this->deploy(); + // provision the applications $this->provision(); } @@ -617,6 +620,27 @@ protected function switchProcessUser() ); } + /** + * Deploys the applications. + * + * @return void + */ + protected function deploy() + { + + // deploy the applications for all containers + /** @var \AppserverIo\Appserver\Core\Interfaces\ContainerInterface $container */ + foreach ($this->getContainers() as $container) { + + // load the containers deployment + $deployment = $container->getDeployment(); + $deployment->injectContainer($container); + + // deploy and initialize the container's applications + $deployment->deploy(); + } + } + /** * Provision the applications. * diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index d35ae0b6f..b4c2f86dd 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -20,7 +20,14 @@ namespace AppserverIo\Appserver\MessageQueue; +use AppserverIo\Storage\GenericStackable; +use AppserverIo\Logger\LoggerUtils; use AppserverIo\Psr\Pms\QueueInterface; +use AppserverIo\Psr\Pms\MessageInterface; +use AppserverIo\Psr\Pms\PriorityKeyInterface; +use AppserverIo\Messaging\Utils\StateActive; +use AppserverIo\Messaging\Utils\PriorityKeys; +use AppserverIo\Psr\Application\ApplicationInterface; /** * A message queue wrapper implementation. @@ -31,36 +38,83 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io */ -class MessageQueue implements QueueInterface +class MessageQueue extends \Thread implements QueueInterface { /** - * The queue name to use. + * Timeout to sleep while waiting for messages. * - * @var string + * @var integer */ - protected $name = null; + const TTL = 1000000; /** - * The message bean type to handle the messages. - * - * @var string + * Initializes the message queue with the necessary data. */ - protected $type = null; + public function __construct() + { + // initialize the flags for start/stop handling + $this->run = true; + $this->running = false; + } /** * Initializes the queue with the name to use. * * @param string $name Holds the queue name to use - * @param string $type The message bean type to handle the messages */ - protected function __construct($name, $type) + public function injectName($name) { $this->name = $name; + } + + /** + * Initializes the queue with the message bean type that has to handle the messages. + * + * @param string $type The message bean type to handle the messages + */ + public function injectType($type) + { $this->type = $type; } + /** + * Inject the application instance the worker is bound to. + * + * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance + * + * @return void + */ + public function injectApplication(ApplicationInterface $application) + { + $this->application = $application; + } + + /** + * Injects the storage for the messages. + * + * @param \AppserverIo\Storage\GenericStackable $queues An storage for the messages + * + * @return void + */ + public function injectMessages(GenericStackable $messages) + { + $this->messages = $messages; + } + + /** + * Injects the storage for the workers. + * + * @param \AppserverIo\Storage\GenericStackable $workers An storage for the workers + * + * @return void + */ + public function injectWorkers(GenericStackable $workers) + { + $this->workers = $workers; + } + /** * Returns the queue name. * @@ -82,15 +136,172 @@ public function getType() } /** - * Initializes and returns a new Queue instance. + * Returns the application instance the worker is bound to. * - * @param string $name Holds the queue name to use - * @param string $type The message bean type to handle the messages + * @return \AppserverIo\Psr\Application\ApplicationInterface The application instance + */ + public function getApplication() + { + return $this->application; + } + + /** + * Returns the storage for the messages. + * + * @return \AppserverIo\Storage\GenericStackable The storage for the messages + */ + public function getMessages() + { + return $this->messages; + } + + /** + * Returns the storage for the workers. + * + * @return \AppserverIo\Storage\GenericStackable The storage for the workers + */ + public function getWorkers() + { + return $this->workers; + } + + /** + * Attach a new message to the queue. + * + * @param \AppserverIo\Psr\Pms\MessageInterface $message The messsage to be attached to the queue + * + * @return void + */ + public function attach(MessageInterface $message) + { + + // force handling the timer tasks now + $this->synchronized(function (MessageQueue $self, MessageInterface $m) { + // create a unique identifier for the priority + $priority = $this->uniqueWorkerName($m->getPriority()); + + // load the worker for the message's priority + if (isset($self->workers[$priority])) { + // attach the message + $self->messages[$m->getMessageId()] = $m; + + // store the job-ID and the PK of the message => necessary to load the message later + $jobWrapper = new \stdClass(); + $jobWrapper->jobId = $m->getMessageId(); + $jobWrapper->messageId = $m->getMessageId(); + + // attach the job to the worker + $self->workers[$priority]->attach($jobWrapper); + } + + }, $this, $message); + } + + /** + * Stops the message queues workers and the message queue itself. + * + * @return void + */ + public function stop() + { + + // stop all workers + foreach ($this->workers as $worker) { + $worker->stop(); + } + + // stop the message queue itself + $this->run = false; + } + + /** + * Creates a unique name to register the worker with the passed priority. + * + * @param \AppserverIo\Psr\Pms\PriorityKeyInterface $priorityKey The priority key to create a unique name for * - * @return \AppserverIo\Appserver\MessageQueue\MessageQueue The instance + * @return string The unique name */ - public static function createQueue($name, $type) + protected function uniqueWorkerName(PriorityKeyInterface $priorityKey) { - return new MessageQueue($name, $type); + return sprintf('%s-%s', $this->getName(), $priorityKey); + } + + /** + * We process the messages/jobs here. + * + * @return void + */ + public function run() + { + + // create a local instance of application and storage + $application = $this->application; + + // register the class loader again, because each thread has its own context + $application->registerClassLoaders(); + + // try to load the profile logger + if ($profileLogger = $application->getInitialContext()->getLogger(LoggerUtils::PROFILE)) { + $profileLogger->appendThreadContext(sprintf('message-queue-%s', $this->getName())); + } + + // create a reference to the workers/messages + $workers = $this->workers; + $messages = $this->messages; + + // prepare the storages + $jobsExecuting = array(); + $jobsToExceute = array(); + $messageStates = array(); + + // initialize the counter for the storages + $counter = 0; + + // create a separate queue for each priority + foreach (PriorityKeys::getAll() as $priorityKey) { + + // create the containers for the worker + $jobsExecuting[$counter] = new GenericStackable(); + $jobsToExceute[$counter] = new GenericStackable(); + $messageStates[$counter] = new GenericStackable(); + + // initialize and start the queue worker + $queueWorker = new QueueWorker(); + $queueWorker->injectMessages($messages); + $queueWorker->injectPriorityKey($priorityKey); + $queueWorker->injectApplication($application); + + // attach the storages + $queueWorker->injectJobsExecuting($jobsExecuting[$counter]); + $queueWorker->injectJobsToExecute($jobsToExceute[$counter]); + $queueWorker->injectMessageStates($messageStates[$counter]); + + // start the worker instance + $queueWorker->start(); + + // add the queue instance to the module + $workers[$this->uniqueWorkerName($priorityKey)] = $queueWorker; + + // raise the counter + $counter++; + } + + // set to TRUE, because message queue is running + $this->running = true; + + // query whether we keep running + while ($this->run) { + + // wait for the configured timeout + $this->wait(MessageQueue::TTL); + + // profile the message queue + if ($profileLogger) { + $profileLogger->debug(sprintf('Process message queue %s', $this->getName())); + } + } + + // set to FALSE, because message queue has been stopped + $this->running = false; } } diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueueModule.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueueModule.php index 6f89c8d23..03aab6535 100644 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueueModule.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueueModule.php @@ -20,18 +20,7 @@ namespace AppserverIo\Appserver\MessageQueue; -use AppserverIo\Http\HttpResponseStates; -use AppserverIo\Storage\GenericStackable; -use AppserverIo\Server\Dictionaries\ServerVars; -use AppserverIo\Server\Dictionaries\ModuleHooks; -use AppserverIo\Server\Interfaces\RequestContextInterface; -use AppserverIo\Server\Interfaces\ServerContextInterface; -use AppserverIo\Server\Exceptions\ModuleException; -use AppserverIo\Psr\HttpMessage\RequestInterface; -use AppserverIo\Psr\HttpMessage\ResponseInterface; -use AppserverIo\Messaging\Utils\PriorityKeys; -use AppserverIo\Messaging\MessageQueueProtocol; -use AppserverIo\Messaging\Utils\StateActive; +use AppserverIo\Appserver\ServletEngine\ServletEngine; /** * A message queue module implementation. @@ -42,7 +31,7 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io */ -class MessageQueueModule +class MessageQueueModule extends ServletEngine { /** @@ -63,144 +52,12 @@ public function getModuleName() } /** - * Initialize the module and the necessary members. - */ - public function __construct() - { - - // initialize the mutex - $this->mutex = \Mutex::create(); - - // initialize the members - $this->queues = new GenericStackable(); - $this->messages = new GenericStackable(); - - // initialize the array containing the worker specific stackables - $this->jobsExecuting = new GenericStackable(); - $this->jobsToExecute = new GenericStackable(); - $this->messageStates = new GenericStackable(); - } - - /** - * Prepares the module for upcoming request in specific context - * - * @return bool - * @throws \AppserverIo\Server\Exceptions\ModuleException - */ - public function prepare() - { - } - - /** - * Initializes the module. - * - * @param \AppserverIo\Server\Interfaces\ServerContextInterface $serverContext The servers context instance + * Initialize the valves that handles the requests. * * @return void - * @throws \AppserverIo\Server\Exceptions\ModuleException */ - public function init(ServerContextInterface $serverContext) + public function initValves() { - try { - // initialize the job counter - $jobCounter = 0; - - // create a queue worker for each application - foreach ($serverContext->getContainer()->getApplications() as $application) { - // load the queue manager to check if there are queues registered for the application - if ($queueManager = $application->search('QueueContextInterface')) { - // if yes, initialize and start the queue worker - foreach ($queueManager->getQueues() as $queue) { - // initialize the queues storage for the priorities - $this->queues[$queueName = $queue->getName()] = new GenericStackable(); - - // create a separate queue for each priority - foreach (PriorityKeys::getAll() as $priorityKey) { - // initialize the stackable for the job storage and the jobs executing - $this->jobsExecuting[$jobCounter] = array(); - $this->jobsToExecute[$jobCounter] = new GenericStackable(); - $this->messageStates[$jobCounter] = new GenericStackable(); - - // initialize and start the queue worker - $queueWorker = new QueueWorker(); - $queueWorker->injectPriorityKey($priorityKey); - $queueWorker->injectApplication($application); - $queueWorker->injectMessages($this->messages); - $queueWorker->injectJobsExecuting($this->jobsExecuting[$jobCounter]); - $queueWorker->injectJobsToExecute($this->jobsToExecute[$jobCounter]); - $queueWorker->injectMessageStates($this->messageStates[$jobCounter]); - $queueWorker->start(); - - // add the queue instance to the module - $this->queues[$queueName][$priorityKey] = $queueWorker; - - // raise the job counter - $jobCounter++; - } - } - } - } - - } catch (\Exception $e) { - throw new ModuleException($e); - } - } - - /** - * Process servlet request. - * - * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object - * @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response A response object - * @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance - * @param int $hook The current hook to process logic for - * - * @return bool - * @throws \AppserverIo\Server\Exceptions\ModuleException - */ - public function process( - RequestInterface $request, - ResponseInterface $response, - RequestContextInterface $requestContext, - $hook - ) { - - try { - // if false hook is coming do nothing - if (ModuleHooks::REQUEST_POST !== $hook) { - return; - } - - // check if we are the handler that has to process this request - if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) !== $this->getModuleName()) { - return; - } - - $message = MessageQueueProtocol::unpack($request->getBodyContent()); - $message->setState(StateActive::get()); - - // load queue name and priority key - $queueName = $message->getDestination()->getName(); - $priorityKey = $message->getPriority(); - - // prevents to attach message to none existing queue - if (isset($this->queues[$queueName][$priorityKey]) === false) { - throw new ModuleException(sprintf("Queue %s not found", $queueName)); - } - - // add the message to the queue - $this->messages[$message->getMessageId()] = $message; - - // attach the message to the queue found as message destination - $queue = $this->queues[$queueName][$priorityKey]; - $queue->attach($message); - - // set response state to be dispatched after this without calling other modules process - $response->setState(HttpResponseStates::DISPATCH); - - } catch (ModuleException $me) { - throw $me; - } catch (\Exception $e) { - throw new ModuleException($e, 500); - } + $this->valves[] = new MessageQueueValve(); } } diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php new file mode 100644 index 000000000..25dca2012 --- /dev/null +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php @@ -0,0 +1,80 @@ + + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ + +namespace AppserverIo\Appserver\MessageQueue; + +use AppserverIo\Messaging\Utils\StateActive; +use AppserverIo\Messaging\MessageQueueProtocol; +use AppserverIo\Appserver\ServletEngine\ValveInterface; +use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface; +use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface; + +/** + * Valve implementation that will be executed by the servlet engine to handle + * an incoming HTTP message request. + * + * @author Tim Wagner + * @copyright 2015 TechDivision GmbH + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @link https://github.com/appserver-io/appserver + * @link http://www.appserver.io + */ +class MessageQueueValve implements ValveInterface +{ + + /** + * Processes the request by invoking the request handler that attaches the message to the + * requested queue in a protected context. + * + * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance + * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance + * + * @return void + * @throws \Exception Is thrown if the requested message queue is not available + */ + public function invoke(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) + { + + // load the application context + /** @var \AppserverIo\Appserver\Application\Application $application */ + $application = $servletRequest->getContext(); + + // unpack the message + $message = MessageQueueProtocol::unpack($servletRequest->getBodyContent()); + + // @todo Not sure if we need that!!!!!! + $message->setState(StateActive::get()); + + // load message queue name and priority key + $queueName = $message->getDestination()->getName(); + $priorityKey = $message->getPriority(); + + // lookup the message queue manager and attach the message + $queueManager = $application->search('QueueContextInterface'); + if ($messageQueue = $queueManager->lookup($queueName)) { + $messageQueue->attach($message); + } else { + throw new \Exception("Can\'t find queue for message queue $queueName"); + } + + // finally dispatch this request, because we have finished processing it + $servletRequest->setDispatched(true); + } +} diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php b/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php index d9ec97a23..4d24b5d21 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php @@ -38,6 +38,28 @@ class QueueLocator implements ResourceLocatorInterface { + /** + * Runs a lookup for the message queue with the passed lookup name and + * session ID. + * + * @param string $lookupName The queue lookup name + * @param string $sessionId The session ID + * @param array $args The arguments passed to the queue + * + * @return \AppserverIo\Psr\Pms\QueueInterface The requested queue instance + */ + public function lookup(QueueContextInterface $queueManager, $lookupName, $sessionId = null, array $args = array()) + { + + // load registered queues + $queues = $queueManager->getQueues(); + + // return the requested message queue for the passed priority key, if available + if (isset($queues[$lookupName])) { + return $queues[$lookupName]; + } + } + /** * Tries to locate the queue that handles the request and returns the instance * if one can be found. @@ -54,7 +76,7 @@ public function locate(QueueContextInterface $queueManager, QueueInterface $queu // load registered queues and requested queue name $queues = $queueManager->getQueues(); - // return the listener of requested queue if available + // return the requested message queue for the passed priority key, if available if (array_key_exists($queueName = $queue->getName(), $queues)) { return $queues[$queueName]; } diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueManager.php b/src/AppserverIo/Appserver/MessageQueue/QueueManager.php index 997d8d4f5..bf0bff457 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueManager.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueManager.php @@ -63,6 +63,30 @@ public function injectQueues(GenericStackable $queues) $this->queues = $queues; } + /** + * Injects the storage for the messages. + * + * @param \AppserverIo\Storage\GenericStackable $queues An storage for the messages + * + * @return void + */ + public function injectMessages(GenericStackable $messages) + { + $this->messages = $messages; + } + + /** + * Injects the storage for the workers. + * + * @param \AppserverIo\Storage\GenericStackable $workers An storage for the workers + * + * @return void + */ + public function injectWorkers(GenericStackable $workers) + { + $this->workers = $workers; + } + /** * Injects the resource locator that locates the requested queue. * @@ -144,32 +168,7 @@ protected function registerMessageQueues(ApplicationInterface $application) // iterate over all found queues and initialize them foreach ($nodes as $node) { - // load the nodes attributes - $attributes = $node->attributes(); - - // load destination queue and receiver type - $destination = (string) $node->destination; - $type = (string) $attributes['type']; - - // create a new queue instance - $instance = MessageQueue::createQueue($destination, $type); - - // register destination and receiver type - $this->queues[$instance->getName()] = $instance; - - // prepare the naming directory to bind the callback to - $path = explode('/', $destination); - - for ($i = 0; $i < sizeof($path) - 1; $i++) { - try { - $this->directories[$i]->search($path[$i]); - } catch (NamingException $ne) { - $this->directories[$i + 1] = $this->directories[$i]->createSubdirectory($path[$i]); - } - } - - // bind the callback for creating a new MQ sender instance to the naming directory => necessary for DI provider - $application->bindCallback($destination, array(&$this, 'createSenderForQueue'), array($destination)); + $this->registeMessageQueue($node); } // if class can not be reflected continue with next class @@ -182,6 +181,49 @@ protected function registerMessageQueues(ApplicationInterface $application) } } + /** + * Deploys the message queue described by the passed XML node. + * + * @param \SimpleXMLElement $node The XML node that describes the message queue + * + * @return void + */ + protected function registeMessageQueue(\SimpleXMLElement $node) + { + + // load the nodes attributes + $attributes = $node->attributes(); + + // load destination queue and receiver type + $destination = (string) $node->destination; + $type = (string) $attributes['type']; + + // initialize the message queue + $messageQueue = new MessageQueue(); + $messageQueue->injectType($type); + $messageQueue->injectName($destination); + $messageQueue->injectWorkers($this->workers); + $messageQueue->injectMessages($this->messages); + $messageQueue->injectApplication($this->application); + $messageQueue->start(); + + // initialize the queues storage for the priorities + $this->queues[$queueName = $messageQueue->getName()] = $messageQueue; + + // prepare the naming directory to bind the callback to + $path = explode('/', $destination); + for ($i = 0; $i < sizeof($path) - 1; $i++) { + try { + $this->directories[$i]->search($path[$i]); + } catch (NamingException $ne) { + $this->directories[$i + 1] = $this->directories[$i]->createSubdirectory($path[$i]); + } + } + + // bind the callback for creating a new MQ sender instance to the naming directory => necessary for DI provider + $this->getApplication()->bindCallback($destination, array(&$this, 'createSenderForQueue'), array($destination)); + } + /** * Returns the array with queue names and the MessageListener class * names as values. @@ -230,7 +272,7 @@ public function locate(QueueInterface $queue) } /** - * Runs a lookup for the message queue with the passed class name and + * Runs a lookup for the message queue with the passed lookup name and * session ID. * * @param string $lookupName The queue lookup name @@ -242,7 +284,7 @@ public function locate(QueueInterface $queue) */ public function lookup($lookupName, $sessionId = null, array $args = array()) { - // still to implement + return $this->getResourceLocator()->lookup($this, $lookupName, $sessionId, $args); } /** diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueManagerFactory.php b/src/AppserverIo/Appserver/MessageQueue/QueueManagerFactory.php index cdfff1317..61b16da89 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueManagerFactory.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueManagerFactory.php @@ -50,8 +50,10 @@ class QueueManagerFactory implements ManagerFactoryInterface public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { - // initialize the stackable for the queues + // initialize the stackable containers $queues = new GenericStackable(); + $workers = new GenericStackable(); + $messages = new GenericStackable(); // initialize the queue locator $queueLocator = new QueueLocator(); @@ -59,6 +61,8 @@ public static function visit(ApplicationInterface $application, ManagerNodeInter // initialize the queue manager $queueManager = new QueueManager(); $queueManager->injectQueues($queues); + $queueManager->injectWorkers($workers); + $queueManager->injectMessages($messages); $queueManager->injectApplication($application); $queueManager->injectResourceLocator($queueLocator); diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 1e003cf05..64208afa2 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -53,6 +53,17 @@ class QueueWorker extends \Thread { + /** + * Initializes the message queue with the necessary data. + */ + public function __construct() + { + + // initialize the flags for start/stop handling + $this->run = true; + $this->running = false; + } + /** * Injects the priority of the queue worker. * @@ -66,63 +77,63 @@ public function injectPriorityKey(PriorityKeyInterface $priorityKey) } /** - * Inject the storage for the jobs to be executed. + * Inject the storage for the messages. * - * @param \AppserverIo\Storage\GenericStackable $jobsToExecute The storage for the jobs to be executed + * @param \AppserverIo\Storage\GenericStackable $messages The storage for the messages * * @return void */ - public function injectJobsToExecute(GenericStackable $jobsToExecute) + public function injectMessages(GenericStackable $messages) { - $this->jobsToExecute = $jobsToExecute; + $this->messages = $messages; } /** - * Inject the storage for the message states. + * Inject the application instance the worker is bound to. * - * @param \AppserverIo\Storage\GenericStackable $messageStates The storage for the message states + * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void */ - public function injectMessageStates(GenericStackable $messageStates) + public function injectApplication(ApplicationInterface $application) { - $this->messageStates = $messageStates; + $this->application = $application; } /** - * Inject the storage for the executing jobs. + * Inject the storage for the jobs to be executed. * - * @param array $jobsExecuting The storage for the executing jobs + * @param \AppserverIo\Storage\GenericStackable $jobsToExecute The storage for the jobs to be executed * * @return void */ - public function injectJobsExecuting(array $jobsExecuting) + public function injectJobsToExecute(GenericStackable $jobsToExecute) { - $this->jobsExecuting = $jobsExecuting; + $this->jobsToExecute = $jobsToExecute; } /** - * Inject the storage for the messages. + * Inject the storage for the message states. * - * @param \AppserverIo\Storage\GenericStackable $messages The storage for the messages + * @param \AppserverIo\Storage\GenericStackable $messageStates The storage for the message states * * @return void */ - public function injectMessages(GenericStackable $messages) + public function injectMessageStates(GenericStackable $messageStates) { - $this->messages = $messages; + $this->messageStates = $messageStates; } /** - * Inject the application instance the worker is bound to. + * Inject the storage for the executing jobs. * - * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance + * @param \AppserverIo\Storage\GenericStackable $jobsExecuting The storage for the executing jobs * * @return void */ - public function injectApplication(ApplicationInterface $application) + public function injectJobsExecuting(GenericStackable $jobsExecuting) { - $this->application = $application; + $this->jobsExecuting = $jobsExecuting; } /** @@ -136,28 +147,23 @@ public function getApplication() } /** - * Attach a new message to the queue. + * Attaches a job for the passed wrapper to the worker instance. * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The messsage to be attached to the queue + * @param \stdClass $jobWrapper The job wrapper to attach the job for * * @return void */ - public function attach(MessageInterface $message) + public function attach(\stdClass $jobWrapper) { // force handling the timer tasks now - $this->synchronized(function (QueueWorker $self, MessageInterface $m) { - - // store the job-ID and the PK of the message => necessary to load the message later - $jobWrapper = new \stdClass(); - $jobWrapper->jobId = $m->getMessageId(); - $jobWrapper->messageId = $m->getMessageId(); + $this->synchronized(function (QueueWorker $self, \stdClass $jw) { // attach the job wrapper - $self->jobsToExecute[$jobWrapper->jobId] = $jobWrapper; - $this->messageStates[$jobWrapper->jobId] = StateActive::KEY; + $this->jobsToExecute[$jw->jobId] = $jw; + $this->messageStates[$jw->jobId] = StateActive::KEY; - }, $this, $message); + }, $this, $jobWrapper); } /** @@ -174,7 +180,7 @@ public function remove(MessageInterface $message) } /** - * Process a message with the state `StateActive. + * Process a message with the state 'StateActive'. * * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed * @@ -182,13 +188,11 @@ public function remove(MessageInterface $message) */ public function processActive(MessageInterface $message) { - - // set new state $this->messageStates[$message->getMessageId()] = StateToProcess::KEY; } /** - * Process a message with the state `StateInProgress. + * Process a message with the state 'StateInProgress'. * * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed * @@ -221,9 +225,8 @@ public function processInProgress(MessageInterface $message) } } - /** - * Process a message with the state `StateProcessed. + * Process a message with the state 'StateProcessed'. * * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed * @@ -238,7 +241,7 @@ public function processProcessed(MessageInterface $message) } /** - * Process a message with the state `StateToProcess. + * Process a message with the state 'StateToProcess'. * * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed * @@ -270,7 +273,7 @@ public function processToProcess(MessageInterface $message) } /** - * Process a message with the state `StateUnknown. + * Process a message with the state 'StateUnknown'. * * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed * @@ -308,15 +311,39 @@ public function processInvalid(MessageInterface $message) } /** - * We process the messages/jobs here. + * Does shutdown logic for request handler if something went wrong and + * produces a fatal error for example. * * @return void + */ + public function shutdown() + { + + // check if there was a fatal error caused shutdown + if ($lastError = error_get_last()) { + // initialize type + message + $type = 0; + $message = ''; + // extract the last error values + extract($lastError); + // query whether we've a fatal/user error + if ($type === E_ERROR || $type === E_USER_ERROR) { + $this->getApplication()->getInitialContex()->getSystemLogger()->error($message); + } + } + } + + /** + * We process the messages/jobs here. * - * @throws \Exception + * @return void */ public function run() { + // register shutdown handler + register_shutdown_function(array(&$this, "shutdown")); + // create a local instance of application and storage $application = $this->application; @@ -345,6 +372,7 @@ public function run() try { // load the message $message = $this->messages[$jobWrapper->jobId]; + // check if we've a message found if ($message instanceof MessageInterface) { // check the message state diff --git a/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php b/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php index 4909cd785..02ab872a7 100644 --- a/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php +++ b/src/AppserverIo/Appserver/ServletEngine/RequestHandler.php @@ -201,9 +201,11 @@ public function shutdown() // check if there was a fatal error caused shutdown if ($lastError = error_get_last()) { + // initialize type + message + $type = 0; + $message = ''; // extract the last error values extract($lastError); - // query whether we've a fatal/user error if ($type === E_ERROR || $type === E_USER_ERROR) { $this->exception = new ServletException($message, 500); From 82995dee1c4c8ebe49f360174c5f9a90de9ef94e Mon Sep 17 00:00:00 2001 From: Bernhard Wick Date: Thu, 30 Apr 2015 11:11:59 +0200 Subject: [PATCH 19/45] Update Setup.php --- src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php b/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php index 8d1a49ba5..05701b790 100644 --- a/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php +++ b/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php @@ -91,6 +91,7 @@ class Setup SetupKeys::OS_DARWIN => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_DARWIN, SetupKeys::OS_ARCHITECTURE => 'x86_64', SetupKeys::GROUP => 'staff', SetupKeys::USER => '_www'), SetupKeys::OS_DEBIAN => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', SetupKeys::GROUP => 'www-data', SetupKeys::USER => 'www-data'), SetupKeys::OS_UBUNTU => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', SetupKeys::GROUP => 'www-data', SetupKeys::USER => 'www-data'), + SetupKeys::OS_ARCH => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', ), SetupKeys::OS_FEDORA => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', ), SetupKeys::OS_REDHAT => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', ), SetupKeys::OS_CENTOS => array(SetupKeys::OS_FAMILY => SetupKeys::OS_FAMILY_LINUX, SetupKeys::OS_ARCHITECTURE => 'x86_64', ), From 8dd7ed9d0ba8f8d8b4f3d9a866eb06aaeb7e7540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Wed, 29 Apr 2015 15:58:07 +0200 Subject: [PATCH 20/45] [FIX] mandatory parameter path is only necessary for sqlite --- .../Appserver/Core/Provisioning/CreateDatabaseStep.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php index d1fd55a2e..700867bd1 100644 --- a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php +++ b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php @@ -143,9 +143,11 @@ public function getConnectionParameters() ); // initialize the path to the database when we use sqlite for example - if ($path = $databaseNode->getPath()->getNodeValue()->__toString()) { - $connectionParameters[CreateDatabaseStep::CONNECTION_PARAM_PATH] = $this->getWebappPath( - ) . DIRECTORY_SEPARATOR . $path; + if ($databaseNode->getPath() instanceof \AppserverIo\Appserver\Core\Api\Node\PathNode) { + if ($path = $databaseNode->getPath()->getNodeValue()->__toString()) { + $connectionParameters[CreateDatabaseStep::CONNECTION_PARAM_PATH] = $this->getWebappPath( + ) . DIRECTORY_SEPARATOR . $path; + } } // set the connection parameters From 959c0f83b2e831a0459983652d323c222744b3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Thu, 30 Apr 2015 09:54:53 +0200 Subject: [PATCH 21/45] [FIX] make xml node check independent from class name --- .../Appserver/Core/Provisioning/CreateDatabaseStep.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php index 700867bd1..2c3e1c66a 100644 --- a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php +++ b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php @@ -143,7 +143,7 @@ public function getConnectionParameters() ); // initialize the path to the database when we use sqlite for example - if ($databaseNode->getPath() instanceof \AppserverIo\Appserver\Core\Api\Node\PathNode) { + if ($databaseNode->getPath()) { if ($path = $databaseNode->getPath()->getNodeValue()->__toString()) { $connectionParameters[CreateDatabaseStep::CONNECTION_PARAM_PATH] = $this->getWebappPath( ) . DIRECTORY_SEPARATOR . $path; From 090048f0e7663e1be334d18477e36a6b11282142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Thu, 30 Apr 2015 09:57:45 +0200 Subject: [PATCH 22/45] [FIX] initialize configurationService before it is used Resolves #769 --- src/AppserverIo/Appserver/Core/GenericDeployment.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/Core/GenericDeployment.php b/src/AppserverIo/Appserver/Core/GenericDeployment.php index 8b0792f7f..f675cf146 100644 --- a/src/AppserverIo/Appserver/Core/GenericDeployment.php +++ b/src/AppserverIo/Appserver/Core/GenericDeployment.php @@ -59,7 +59,8 @@ protected function deployDatasources() // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration foreach ($datasourceFiles as $datasourceFile) { // validate the file, but skip it if validation fails - if ($this->getConfigurationService()->validateFile($datasourceFile) === false) { + $configurationService = $this->getConfigurationService(); + if ($configurationService->validateFile($datasourceFile) === false) { $errorMessages = $configurationService->getErrorMessages(); $systemLogger = $this->getInitialContext()->getSystemLogger(); $systemLogger->error(reset($errorMessages)); From 878b626840b603c62e1cbc35a4259ef20e96e5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Thu, 30 Apr 2015 10:00:44 +0200 Subject: [PATCH 23/45] [TASK] database provisioning should be possible with MySQL PDO Addresses #770 --- .../Core/Provisioning/CreateDatabaseStep.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php index 2c3e1c66a..a4fa8b3a9 100644 --- a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php +++ b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php @@ -72,6 +72,13 @@ class CreateDatabaseStep extends AbstractStep */ const CONNECTION_PARAM_PASSWORD = 'password'; + /** + * The DB connection parameter with the databaseName to connect. + * + * @var string + */ + const CONNECTION_PARAM_DATABASENAME = 'dbname'; + /** * Executes the functionality for this step, in this case the execution of * the PHP script defined in the step configuration. @@ -150,6 +157,11 @@ public function getConnectionParameters() } } + if ($databaseNode->getDatabaseName()) { + $databaseName = $databaseNode->getDatabaseName()->getNodeValue()->__toString(); + $connectionParameters[CreateDatabaseStep::CONNECTION_PARAM_DATABASENAME] = $databaseName; + } + // set the connection parameters return $connectionParameters; } From e6708aadcb913efce98823232f04c2191cb53525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Thu, 30 Apr 2015 10:26:20 +0200 Subject: [PATCH 24/45] [TASK] move configurationService assignment out of loop Addresses #769 --- src/AppserverIo/Appserver/Core/GenericDeployment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/Core/GenericDeployment.php b/src/AppserverIo/Appserver/Core/GenericDeployment.php index f675cf146..5cf8180a8 100644 --- a/src/AppserverIo/Appserver/Core/GenericDeployment.php +++ b/src/AppserverIo/Appserver/Core/GenericDeployment.php @@ -57,9 +57,9 @@ protected function deployDatasources() // load the datasource files $datasourceFiles = $this->getDeploymentService()->globDir($directory . DIRECTORY_SEPARATOR . '*-ds.xml'); // iterate through all provisioning files (provision.xml), validate them and attach them to the configuration + $configurationService = $this->getConfigurationService(); foreach ($datasourceFiles as $datasourceFile) { // validate the file, but skip it if validation fails - $configurationService = $this->getConfigurationService(); if ($configurationService->validateFile($datasourceFile) === false) { $errorMessages = $configurationService->getErrorMessages(); $systemLogger = $this->getInitialContext()->getSystemLogger(); From 80e9a84eaa0009feda423a70f2a72cf7629c5e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20Ho=CC=88chtl?= Date: Thu, 30 Apr 2015 10:29:13 +0200 Subject: [PATCH 25/45] [CGL] indentations whitespaces Addresses #770 --- .../Core/Provisioning/CreateDatabaseStep.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php index a4fa8b3a9..381a27966 100644 --- a/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php +++ b/src/AppserverIo/Appserver/Core/Provisioning/CreateDatabaseStep.php @@ -64,7 +64,6 @@ class CreateDatabaseStep extends AbstractStep */ const CONNECTION_PARAM_USER = 'user'; - /** * The DB connection parameter with the passwort to connect. * @@ -72,12 +71,12 @@ class CreateDatabaseStep extends AbstractStep */ const CONNECTION_PARAM_PASSWORD = 'password'; - /** - * The DB connection parameter with the databaseName to connect. - * - * @var string - */ - const CONNECTION_PARAM_DATABASENAME = 'dbname'; + /** + * The DB connection parameter with the databaseName to connect. + * + * @var string + */ + const CONNECTION_PARAM_DATABASENAME = 'dbname'; /** * Executes the functionality for this step, in this case the execution of From f2dbcef2356898f5bc55bc5b7c78e2c44ff06cd5 Mon Sep 17 00:00:00 2001 From: wagnert Date: Sat, 2 May 2015 22:55:49 +0200 Subject: [PATCH 26/45] Add application AFTER connecting it to the container --- src/AppserverIo/Appserver/Core/AbstractContainerThread.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php index 534b819b0..2d69bcbb9 100644 --- a/src/AppserverIo/Appserver/Core/AbstractContainerThread.php +++ b/src/AppserverIo/Appserver/Core/AbstractContainerThread.php @@ -381,12 +381,12 @@ public function addApplicationToSystemConfiguration(ApplicationInterface $applic public function addApplication(ApplicationInterface $application) { - // register the application in this instance - $this->applications[$application->getName()] = $application; - // adds the application to the system configuration $this->addApplicationToSystemConfiguration($application); + // register the application in this instance + $this->applications[$application->getName()] = $application; + // log a message that the app has been started $this->getInitialContext()->getSystemLogger()->debug( sprintf('Successfully initialized and deployed app %s', $application->getName()) From 037887fa3239eeb00d6a9087d1db67aaa385e4dd Mon Sep 17 00:00:00 2001 From: wagnert Date: Sun, 3 May 2015 00:24:48 +0200 Subject: [PATCH 27/45] Fix PSR-2 errors --- src/AppserverIo/Appserver/MessageQueue/MessageQueue.php | 8 +++++--- src/AppserverIo/Appserver/MessageQueue/QueueLocator.php | 7 ++++--- src/AppserverIo/Appserver/MessageQueue/QueueManager.php | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index b4c2f86dd..c5e04b58b 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -63,6 +63,8 @@ public function __construct() * Initializes the queue with the name to use. * * @param string $name Holds the queue name to use + * + * @return void */ public function injectName($name) { @@ -73,6 +75,8 @@ public function injectName($name) * Initializes the queue with the message bean type that has to handle the messages. * * @param string $type The message bean type to handle the messages + * + * @return void */ public function injectType($type) { @@ -94,7 +98,7 @@ public function injectApplication(ApplicationInterface $application) /** * Injects the storage for the messages. * - * @param \AppserverIo\Storage\GenericStackable $queues An storage for the messages + * @param \AppserverIo\Storage\GenericStackable $messages An storage for the messages * * @return void */ @@ -259,7 +263,6 @@ public function run() // create a separate queue for each priority foreach (PriorityKeys::getAll() as $priorityKey) { - // create the containers for the worker $jobsExecuting[$counter] = new GenericStackable(); $jobsToExceute[$counter] = new GenericStackable(); @@ -291,7 +294,6 @@ public function run() // query whether we keep running while ($this->run) { - // wait for the configured timeout $this->wait(MessageQueue::TTL); diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php b/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php index 4d24b5d21..06af3b7c5 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueLocator.php @@ -42,9 +42,10 @@ class QueueLocator implements ResourceLocatorInterface * Runs a lookup for the message queue with the passed lookup name and * session ID. * - * @param string $lookupName The queue lookup name - * @param string $sessionId The session ID - * @param array $args The arguments passed to the queue + * @param \AppserverIo\Psr\Pms\QueueContextInterface $queueManager The queue manager instance + * @param string $lookupName The queue lookup name + * @param string $sessionId The session ID + * @param array $args The arguments passed to the queue * * @return \AppserverIo\Psr\Pms\QueueInterface The requested queue instance */ diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueManager.php b/src/AppserverIo/Appserver/MessageQueue/QueueManager.php index bf0bff457..a92ead883 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueManager.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueManager.php @@ -66,7 +66,7 @@ public function injectQueues(GenericStackable $queues) /** * Injects the storage for the messages. * - * @param \AppserverIo\Storage\GenericStackable $queues An storage for the messages + * @param \AppserverIo\Storage\GenericStackable $messages An storage for the messages * * @return void */ From aa691f6d53d1c9faf68eaa8fd6d32eafd028b6b4 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Tue, 5 May 2015 12:26:26 +0200 Subject: [PATCH 28/45] Minor Refactoring --- src/AppserverIo/Appserver/MessageQueue/MessageQueue.php | 4 +++- src/AppserverIo/Appserver/MessageQueue/QueueWorker.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index c5e04b58b..d03f5b078 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -295,7 +295,9 @@ public function run() // query whether we keep running while ($this->run) { // wait for the configured timeout - $this->wait(MessageQueue::TTL); + $this->synchronized(function ($self) { + $self->wait(MessageQueue::TTL); + }, $this); // profile the message queue if ($profileLogger) { diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 64208afa2..60e2f93f0 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -160,8 +160,8 @@ public function attach(\stdClass $jobWrapper) $this->synchronized(function (QueueWorker $self, \stdClass $jw) { // attach the job wrapper - $this->jobsToExecute[$jw->jobId] = $jw; - $this->messageStates[$jw->jobId] = StateActive::KEY; + $self->jobsToExecute[$jw->jobId] = $jw; + $self->messageStates[$jw->jobId] = StateActive::KEY; }, $this, $jobWrapper); } From 03203283c43c314c04caca90b32fa2a8ef3cd83e Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Tue, 5 May 2015 13:43:33 +0200 Subject: [PATCH 29/45] Update CHANGELOG.md and switch to 1.0.5 --- CHANGELOG.md | 10 ++++++++++ build.default.properties | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad6113e11..d8f414ff9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# Version 1.0.5 + +## Bugfixes + +* Fixed [#784](https://github.com/appserver-io/appserver/issues/784) - Application Deployment after switching to safe user + +## Features + +* None + # Version 1.0.4 ## Bugfixes diff --git a/build.default.properties b/build.default.properties index 061efce2f..e0c174cae 100644 --- a/build.default.properties +++ b/build.default.properties @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------------- # ---- Module Release Settings -------------------------------------------------- -release.version = 1.0.4 +release.version = 1.0.5 release.name = Iron Horse # ---- PHPCPD Settings ---------------------------------------------------------- From 866f87a162c1324c2cfd0203f520ae8c441773e2 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Wed, 6 May 2015 14:24:28 +0200 Subject: [PATCH 30/45] Switch from Stackable to array to avoid Windows segfaults --- src/AppserverIo/Appserver/MessageQueue/MessageQueue.php | 5 ++++- src/AppserverIo/Appserver/MessageQueue/QueueWorker.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index d03f5b078..3371670d3 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -263,8 +263,11 @@ public function run() // create a separate queue for each priority foreach (PriorityKeys::getAll() as $priorityKey) { + // ATTENTION: We use an array for the jobs (threads) that are executing acutually. + // Using stackables leads to random segfaults on Windows! + $jobsExecuting[$counter] = array(); + // create the containers for the worker - $jobsExecuting[$counter] = new GenericStackable(); $jobsToExceute[$counter] = new GenericStackable(); $messageStates[$counter] = new GenericStackable(); diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 60e2f93f0..b3a035b8a 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -127,11 +127,11 @@ public function injectMessageStates(GenericStackable $messageStates) /** * Inject the storage for the executing jobs. * - * @param \AppserverIo\Storage\GenericStackable $jobsExecuting The storage for the executing jobs + * @param array $jobsExecuting The storage for the executing jobs * * @return void */ - public function injectJobsExecuting(GenericStackable $jobsExecuting) + public function injectJobsExecuting(array $jobsExecuting) { $this->jobsExecuting = $jobsExecuting; } From 58d28763d6bc3a02ae4f2da7608c7bc250f9eb6c Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Wed, 6 May 2015 14:27:27 +0200 Subject: [PATCH 31/45] Extend CHANGELOG.md with switch to PHP 5.5.24 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8f414ff9..79302c813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ ## Features -* None +* Closed [#758](https://github.com/appserver-io/appserver/issues/758) - Update to latest PHP 5.5.24 # Version 1.0.4 From 1f96558e8902f4a4977c9c37dba43d2cf41ba479 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 7 May 2015 13:41:52 +0200 Subject: [PATCH 32/45] Fixed #790 - Long running messages in Message Queue blocks other messages Closed #777 - Remove remote http://www.w3.org/2001/03/xml.xsd from schemas and configurations --- CHANGELOG.md | 2 + UPGRADE-1.0.5.md | 3 + resources/schema/appserver.xsd | 2 +- resources/schema/xml.xsd | 117 +++++++++ .../Appserver/MessageQueue/QueueWorker.php | 243 +++++++----------- 5 files changed, 212 insertions(+), 155 deletions(-) create mode 100644 UPGRADE-1.0.5.md create mode 100644 resources/schema/xml.xsd diff --git a/CHANGELOG.md b/CHANGELOG.md index 79302c813..fc23335e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,11 @@ ## Bugfixes * Fixed [#784](https://github.com/appserver-io/appserver/issues/784) - Application Deployment after switching to safe user +* Fixed [#790](https://github.com/appserver-io/appserver/issues/790) - Long running messages in Message Queue blocks other messages ## Features +* Remove [#777](https://github.com/appserver-io/appserver/issues/777) - Remove remote http://www.w3.org/2001/03/xml.xsd from schemas and configurations * Closed [#758](https://github.com/appserver-io/appserver/issues/758) - Update to latest PHP 5.5.24 # Version 1.0.4 diff --git a/UPGRADE-1.0.5.md b/UPGRADE-1.0.5.md new file mode 100644 index 000000000..0545fdcec --- /dev/null +++ b/UPGRADE-1.0.5.md @@ -0,0 +1,3 @@ +# Upgrade from 1.0.4 to 1.0.5 + +Updating from 1.0.4 to 1.0.5 doesn't have any impacts. Please read the apropriate UPGRADE-1.x.x files for updates from older versions to 1.0.4. diff --git a/resources/schema/appserver.xsd b/resources/schema/appserver.xsd index 0f884dd31..69cc7d5f8 100644 --- a/resources/schema/appserver.xsd +++ b/resources/schema/appserver.xsd @@ -4,7 +4,7 @@ targetNamespace="http://www.appserver.io/appserver" elementFormDefault="unqualified" attributeFormDefault="unqualified"> - + diff --git a/resources/schema/xml.xsd b/resources/schema/xml.xsd new file mode 100644 index 000000000..d662b4236 --- /dev/null +++ b/resources/schema/xml.xsd @@ -0,0 +1,117 @@ + + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang or xml:space attributes + on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2001/03/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself. In other words, if the XML Schema namespace changes, the version + of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2001/03/xml.xsd will not change. + + + + + + In due course, we should install the relevant ISO 2- and 3-letter + codes as the enumerated possible values . . . + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + + + + + diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index b3a035b8a..9f4b9f51e 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -43,6 +43,7 @@ * @link https://github.com/appserver-io/appserver * @link http://www.appserver.io * + * @property boolean $run Flag to start/stop the worker * @property \AppserverIo\Psr\Application\ApplicationInterface $application The application instance with the queue manager/locator * @property \AppserverIo\Storage\GenericStackable $jobsExecuting The storage for the jobs currently executing * @property \AppserverIo\Storage\GenericStackable $jobsToExecute The storage for the jobs to be executed @@ -54,14 +55,11 @@ class QueueWorker extends \Thread { /** - * Initializes the message queue with the necessary data. + * Sets the workers start flag. */ public function __construct() { - - // initialize the flags for start/stop handling $this->run = true; - $this->running = false; } /** @@ -167,147 +165,15 @@ public function attach(\stdClass $jobWrapper) } /** - * Removes the message from the queue. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be removed from the queue - * - * @return void - */ - public function remove(MessageInterface $message) - { - unset($this->messages[$message->getMessageId()]); - unset($this->messageStates[$message->getMessageId()]); - } - - /** - * Process a message with the state 'StateActive'. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed - * - * @return void - */ - public function processActive(MessageInterface $message) - { - $this->messageStates[$message->getMessageId()] = StateToProcess::KEY; - } - - /** - * Process a message with the state 'StateInProgress'. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed - * - * @return void - */ - public function processInProgress(MessageInterface $message) - { - - // make sure the job has been finished - if (isset($this->jobsExecuting[$message->getMessageId()]) && - $this->jobsExecuting[$message->getMessageId()] instanceof JobInterface && - $this->jobsExecuting[$message->getMessageId()]->isFinished() - ) { - // log a message that the job is still in progress - $this->getApplication()->getInitialContext()->getSystemLogger()->info( - sprintf('Job %s has been finished, remove it from job queue now', $message->getMessageId()) - ); - - // we also remove the job - unset($this->jobsExecuting[$message->getMessageId()]); - - // set new state - $this->messageStates[$message->getMessageId()] = StateProcessed::KEY; - - } else { - // log a message that the job is still in progress - $this->getApplication()->getInitialContext()->getSystemLogger()->debug( - sprintf('Job %s is still in progress', $message->getMessageId()) - ); - } - } - - /** - * Process a message with the state 'StateProcessed'. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed - * - * @return void - */ - public function processProcessed(MessageInterface $message) - { - // remove the job from the queue with jobs that has to be executed - unset($this->jobsToExecute[$message->getMessageId()]); - // remove the message from the queue - $this->remove($message); - } - - /** - * Process a message with the state 'StateToProcess'. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed - * - * @return void - */ - public function processToProcess(MessageInterface $message) - { - - // count messages in queue - $inQueue = sizeof($this->jobsExecuting); - - // we only process 50 jobs in parallel - if ($inQueue < 50) { - // load application - $application = $this->getApplication(); - - // start the job and add it to the internal array - $this->jobsExecuting[$message->getMessageId()] = new Job($message, $application); - - // set new state - $this->messageStates[$message->getMessageId()] = StateInProgress::KEY; - - } else { - // log a message that queue is actually full - $this->getApplication()->getInitialContext()->getSystemLogger()->debug( - sprintf('Job queue full - (%d jobs/%d msg wait)', $inQueue, sizeof($this->messages)) - ); - } - } - - /** - * Process a message with the state 'StateUnknown'. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed - * - * @return void - */ - public function processUnknown(MessageInterface $message) - { - - // set new state - $this->messageStates[$message->getMessageId()] = StateFailed::KEY; - - // log a message that we've a message with a unknown state - $this->getApplication()->getInitialContext()->getSystemLogger()->critical( - sprintf('Message %s has state %s', $message->getMessageId(), StateFailed::KEY) - ); - } - - /** - * Process a message with an invalid state. - * - * @param \AppserverIo\Psr\Pms\MessageInterface $message The message to be processed + * Stops the worker instance. * * @return void */ - public function processInvalid(MessageInterface $message) + public function stop() { - - // set new state - $this->messageStates[$message->getMessageId()] = StateFailed::KEY; - - // log a message that we've a message with an invalid state - $this->getApplication()->getInitialContext()->getSystemLogger()->critical( - sprintf('Message %s has an invalid state', $message->getMessageId()) - ); + $this->synchronized(function ($self) { + $self->run = false; + }, $this); } /** @@ -328,7 +194,7 @@ public function shutdown() extract($lastError); // query whether we've a fatal/user error if ($type === E_ERROR || $type === E_USER_ERROR) { - $this->getApplication()->getInitialContex()->getSystemLogger()->error($message); + $this->getApplication()->getInitialContext()->getSystemLogger()->error($message); } } } @@ -347,12 +213,19 @@ public function run() // create a local instance of application and storage $application = $this->application; + // create local instances of the storages + $messages = $this->messages; + $priorityKey = $this->priorityKey; + $messageStates = $this->messageStates; + $jobsToExecute = $this->jobsToExecute; + $jobsExecuting = $this->jobsExecuting; + // register the class loader again, because each thread has its own context $application->registerClassLoaders(); // try to load the profile logger if ($profileLogger = $application->getInitialContext()->getLogger(LoggerUtils::PROFILE)) { - $profileLogger->appendThreadContext(sprintf('queue-worker-%s', $this->priorityKey)); + $profileLogger->appendThreadContext(sprintf('queue-worker-%s', $priorityKey)); } /* @@ -363,57 +236,119 @@ public function run() * PriorityMedium: 10.000 === 0.01 s * PriorityLow: 1.000.000 === 1 s */ - $sleepFor = pow(10, $this->priorityKey->getPriority() * 2); + $sleepFor = pow(10, $priorityKey->getPriority() * 2); // run forever while (true) { // iterate over all job wrappers - foreach ($this->jobsToExecute as $jobWrapper) { + foreach ($jobsToExecute as $jobWrapper) { try { // load the message - $message = $this->messages[$jobWrapper->jobId]; + $message = $messages[$jobWrapper->jobId]; // check if we've a message found if ($message instanceof MessageInterface) { // check the message state - switch ($this->messageStates[$jobWrapper->jobId]) { + switch ($messageStates[$jobWrapper->jobId]) { // message is active and ready to be processed case StateActive::KEY: - $this->processActive($message); + // set the new state now + $messageStates[$message->getMessageId()] = StateToProcess::KEY; + break; // message is paused or in progress case StatePaused::KEY: case StateInProgress::KEY: - $this->processInProgress($message); + // make sure the job has been finished + if (isset($jobsExecuting[$message->getMessageId()]) && + $jobsExecuting[$message->getMessageId()] instanceof JobInterface && + $jobsExecuting[$message->getMessageId()]->isFinished() + ) { + // log a message that the job is still in progress + $this->getApplication()->getInitialContext()->getSystemLogger()->info( + sprintf('Job %s has been finished, remove it from job queue now', $message->getMessageId()) + ); + + // we also remove the job + unset($jobsExecuting[$message->getMessageId()]); + + // set the new state now + $messageStates[$message->getMessageId()] = StateProcessed::KEY; + + } else { + // log a message that the job is still in progress + $this->getApplication()->getInitialContext()->getSystemLogger()->debug( + sprintf('Job %s is still in progress', $message->getMessageId()) + ); + } + break; // message processing failed or has been successfully processed case StateFailed::KEY: case StateProcessed::KEY: - $this->processProcessed($message); + // remove the job from the queue with jobs that has to be executed + unset($jobsToExecute[$message->getMessageId()]); + + // remove the message from the queue + unset($messages[$message->getMessageId()]); + unset($messageStates[$message->getMessageId()]); + break; // message has to be processed now case StateToProcess::KEY: - $this->processToProcess($message); + // count messages in queue + $inQueue = sizeof($jobsExecuting); + + // we only process 50 jobs in parallel + if ($inQueue < 50) { + + // start the job and add it to the internal array + $jobsExecuting[$message->getMessageId()] = new Job($message, $application); + + // set the new state now + $messageStates[$message->getMessageId()] = StateInProgress::KEY; + + } else { + // log a message that queue is actually full + $application->getInitialContext()->getSystemLogger()->debug( + sprintf('Job queue full - (%d jobs/%d msg wait)', $inQueue, sizeof($messages)) + ); + } + break; // message is in an unknown state -> this is weired and should never happen! case StateUnknown::KEY: - $this->processUnknown($message); + // set new state now + $messageStates[$message->getMessageId()] = StateFailed::KEY; + + // log a message that we've a message with a unknown state + $this->getApplication()->getInitialContext()->getSystemLogger()->critical( + sprintf('Message %s has state %s', $message->getMessageId(), StateFailed::KEY) + ); + break; // we don't know the message state -> this is weired and should never happen! default: - $this->processInvalid($message); + // set new state + $messageStates[$message->getMessageId()] = StateFailed::KEY; + + // log a message that we've a message with an invalid state + $this->getApplication()->getInitialContext()->getSystemLogger()->critical( + sprintf('Message %s has an invalid state', $message->getMessageId()) + ); + break; } } @@ -430,7 +365,7 @@ public function run() // profile the size of the session pool if ($profileLogger) { $profileLogger->debug( - sprintf('Processed queue worker with priority %s, size of queue size is: %d', $this->priorityKey, sizeof($this->storage)) + sprintf('Processed queue worker with priority %s, size of queue size is: %d', $priorityKey, sizeof($jobsToExecute)) ); } From 905a8df852ede64cb28b39f63ebb7eedcf2f348a Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 7 May 2015 14:37:51 +0200 Subject: [PATCH 33/45] Query run flag in queue workers while loop --- .../Appserver/MessageQueue/MessageQueue.php | 26 +++++++++++++++++++ .../Appserver/MessageQueue/QueueWorker.php | 6 ++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index 3371670d3..34d619e4c 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -230,6 +230,29 @@ protected function uniqueWorkerName(PriorityKeyInterface $priorityKey) return sprintf('%s-%s', $this->getName(), $priorityKey); } + /** + * Does shutdown logic for request handler if something went wrong and + * produces a fatal error for example. + * + * @return void + */ + public function shutdown() + { + + // check if there was a fatal error caused shutdown + if ($lastError = error_get_last()) { + // initialize type + message + $type = 0; + $message = ''; + // extract the last error values + extract($lastError); + // query whether we've a fatal/user error + if ($type === E_ERROR || $type === E_USER_ERROR) { + $this->getApplication()->getInitialContex()->getSystemLogger()->error($message); + } + } + } + /** * We process the messages/jobs here. * @@ -238,6 +261,9 @@ protected function uniqueWorkerName(PriorityKeyInterface $priorityKey) public function run() { + // register shutdown handler + register_shutdown_function(array(&$this, "shutdown")); + // create a local instance of application and storage $application = $this->application; diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 9f4b9f51e..d8233f567 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -238,8 +238,8 @@ public function run() */ $sleepFor = pow(10, $priorityKey->getPriority() * 2); - // run forever - while (true) { + // run until we've to stop + while ($this->run) { // iterate over all job wrappers foreach ($jobsToExecute as $jobWrapper) { try { @@ -296,8 +296,8 @@ public function run() unset($jobsToExecute[$message->getMessageId()]); // remove the message from the queue - unset($messages[$message->getMessageId()]); unset($messageStates[$message->getMessageId()]); + unset($messages[$message->getMessageId()]); break; From be758d09ba7c088943a9cbd8e4dbdf2e5a9a5494 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 7 May 2015 14:37:51 +0200 Subject: [PATCH 34/45] Query run flag in queue workers while loop Fixed some possible segfault risks --- .../Appserver/MessageQueue/MessageQueue.php | 34 ++++++-- .../MessageQueue/MessageQueueValve.php | 3 - .../Appserver/MessageQueue/QueueWorker.php | 82 ++++++++----------- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index 3371670d3..3b175225c 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -230,6 +230,29 @@ protected function uniqueWorkerName(PriorityKeyInterface $priorityKey) return sprintf('%s-%s', $this->getName(), $priorityKey); } + /** + * Does shutdown logic for request handler if something went wrong and + * produces a fatal error for example. + * + * @return void + */ + public function shutdown() + { + + // check if there was a fatal error caused shutdown + if ($lastError = error_get_last()) { + // initialize type + message + $type = 0; + $message = ''; + // extract the last error values + extract($lastError); + // query whether we've a fatal/user error + if ($type === E_ERROR || $type === E_USER_ERROR) { + $this->getApplication()->getInitialContext()->getSystemLogger()->error($message); + } + } + } + /** * We process the messages/jobs here. * @@ -238,6 +261,9 @@ protected function uniqueWorkerName(PriorityKeyInterface $priorityKey) public function run() { + // register shutdown handler + register_shutdown_function(array(&$this, "shutdown")); + // create a local instance of application and storage $application = $this->application; @@ -254,22 +280,16 @@ public function run() $messages = $this->messages; // prepare the storages - $jobsExecuting = array(); $jobsToExceute = array(); - $messageStates = array(); // initialize the counter for the storages $counter = 0; // create a separate queue for each priority foreach (PriorityKeys::getAll() as $priorityKey) { - // ATTENTION: We use an array for the jobs (threads) that are executing acutually. - // Using stackables leads to random segfaults on Windows! - $jobsExecuting[$counter] = array(); // create the containers for the worker $jobsToExceute[$counter] = new GenericStackable(); - $messageStates[$counter] = new GenericStackable(); // initialize and start the queue worker $queueWorker = new QueueWorker(); @@ -278,9 +298,7 @@ public function run() $queueWorker->injectApplication($application); // attach the storages - $queueWorker->injectJobsExecuting($jobsExecuting[$counter]); $queueWorker->injectJobsToExecute($jobsToExceute[$counter]); - $queueWorker->injectMessageStates($messageStates[$counter]); // start the worker instance $queueWorker->start(); diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php index 25dca2012..c54c3f255 100644 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueueValve.php @@ -59,9 +59,6 @@ public function invoke(HttpServletRequestInterface $servletRequest, HttpServletR // unpack the message $message = MessageQueueProtocol::unpack($servletRequest->getBodyContent()); - // @todo Not sure if we need that!!!!!! - $message->setState(StateActive::get()); - // load message queue name and priority key $queueName = $message->getDestination()->getName(); $priorityKey = $message->getPriority(); diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 9f4b9f51e..600e16ecf 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -45,10 +45,8 @@ * * @property boolean $run Flag to start/stop the worker * @property \AppserverIo\Psr\Application\ApplicationInterface $application The application instance with the queue manager/locator - * @property \AppserverIo\Storage\GenericStackable $jobsExecuting The storage for the jobs currently executing * @property \AppserverIo\Storage\GenericStackable $jobsToExecute The storage for the jobs to be executed * @property \AppserverIo\Storage\GenericStackable $messages The storage for the messages - * @property \AppserverIo\Storage\GenericStackable $messageStates The storage for the messages' states * @property \AppserverIo\Psr\Pms\PriorityKeyInterface $priorityKey The priority of this queue worker */ class QueueWorker extends \Thread @@ -86,18 +84,6 @@ public function injectMessages(GenericStackable $messages) $this->messages = $messages; } - /** - * Inject the application instance the worker is bound to. - * - * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance - * - * @return void - */ - public function injectApplication(ApplicationInterface $application) - { - $this->application = $application; - } - /** * Inject the storage for the jobs to be executed. * @@ -111,27 +97,15 @@ public function injectJobsToExecute(GenericStackable $jobsToExecute) } /** - * Inject the storage for the message states. - * - * @param \AppserverIo\Storage\GenericStackable $messageStates The storage for the message states - * - * @return void - */ - public function injectMessageStates(GenericStackable $messageStates) - { - $this->messageStates = $messageStates; - } - - /** - * Inject the storage for the executing jobs. + * Inject the application instance the worker is bound to. * - * @param array $jobsExecuting The storage for the executing jobs + * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void */ - public function injectJobsExecuting(array $jobsExecuting) + public function injectApplication(ApplicationInterface $application) { - $this->jobsExecuting = $jobsExecuting; + $this->application = $application; } /** @@ -154,13 +128,9 @@ public function getApplication() public function attach(\stdClass $jobWrapper) { - // force handling the timer tasks now + // attach the job wrapper $this->synchronized(function (QueueWorker $self, \stdClass $jw) { - - // attach the job wrapper $self->jobsToExecute[$jw->jobId] = $jw; - $self->messageStates[$jw->jobId] = StateActive::KEY; - }, $this, $jobWrapper); } @@ -216,9 +186,11 @@ public function run() // create local instances of the storages $messages = $this->messages; $priorityKey = $this->priorityKey; - $messageStates = $this->messageStates; $jobsToExecute = $this->jobsToExecute; - $jobsExecuting = $this->jobsExecuting; + + // initialize the arrays for the message states and the jobs executing + $messageStates = array(); + $jobsExecuting = array(); // register the class loader again, because each thread has its own context $application->registerClassLoaders(); @@ -238,8 +210,8 @@ public function run() */ $sleepFor = pow(10, $priorityKey->getPriority() * 2); - // run forever - while (true) { + // run until we've to stop + while ($this->run) { // iterate over all job wrappers foreach ($jobsToExecute as $jobWrapper) { try { @@ -248,6 +220,17 @@ public function run() // check if we've a message found if ($message instanceof MessageInterface) { + // set the inital message state if not done + if (isset($messageStates[$jobWrapper->jobId]) === false) { + + // initialize the default message state + if ($state = $message->getState()) { + $messageStates[$jobWrapper->jobId] = $state->getState(); + } else { + $messageStates[$jobWrapper->jobId] = StateUnknown::KEY; + } + } + // check the message state switch ($messageStates[$jobWrapper->jobId]) { @@ -273,9 +256,6 @@ public function run() sprintf('Job %s has been finished, remove it from job queue now', $message->getMessageId()) ); - // we also remove the job - unset($jobsExecuting[$message->getMessageId()]); - // set the new state now $messageStates[$message->getMessageId()] = StateProcessed::KEY; @@ -292,12 +272,18 @@ public function run() case StateFailed::KEY: case StateProcessed::KEY: + // load the unique message-ID + $messageId = $message->getMessageId(); + // remove the job from the queue with jobs that has to be executed - unset($jobsToExecute[$message->getMessageId()]); + unset($jobsToExecute[$messageId]); + + // also remove the job + unset($jobsExecuting[$messageId]); - // remove the message from the queue - unset($messages[$message->getMessageId()]); - unset($messageStates[$message->getMessageId()]); + // finally, remove the message states and the message from the queue + unset($messageStates[$messageId]); + unset($messages[$messageId]); break; @@ -311,7 +297,7 @@ public function run() if ($inQueue < 50) { // start the job and add it to the internal array - $jobsExecuting[$message->getMessageId()] = new Job($message, $application); + $jobsExecuting[$message->getMessageId()] = new Job(clone $message, $application); // set the new state now $messageStates[$message->getMessageId()] = StateInProgress::KEY; @@ -341,7 +327,7 @@ public function run() // we don't know the message state -> this is weired and should never happen! default: - // set new state + // set the failed message state $messageStates[$message->getMessageId()] = StateFailed::KEY; // log a message that we've a message with an invalid state From 1f404c2a5442c7405fe6612ff4ddb235500904cc Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Thu, 7 May 2015 16:51:58 +0200 Subject: [PATCH 35/45] Make PSR-2 compatible --- src/AppserverIo/Appserver/MessageQueue/MessageQueue.php | 1 - src/AppserverIo/Appserver/MessageQueue/QueueWorker.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php index 3b175225c..a368ce75d 100755 --- a/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php +++ b/src/AppserverIo/Appserver/MessageQueue/MessageQueue.php @@ -287,7 +287,6 @@ public function run() // create a separate queue for each priority foreach (PriorityKeys::getAll() as $priorityKey) { - // create the containers for the worker $jobsToExceute[$counter] = new GenericStackable(); diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 600e16ecf..5cffaedbc 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -222,7 +222,6 @@ public function run() if ($message instanceof MessageInterface) { // set the inital message state if not done if (isset($messageStates[$jobWrapper->jobId]) === false) { - // initialize the default message state if ($state = $message->getState()) { $messageStates[$jobWrapper->jobId] = $state->getState(); @@ -295,7 +294,6 @@ public function run() // we only process 50 jobs in parallel if ($inQueue < 50) { - // start the job and add it to the internal array $jobsExecuting[$message->getMessageId()] = new Job(clone $message, $application); From abc27e6b42aedbf9cbe5c179ff2be51ff46b6f17 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Fri, 8 May 2015 14:37:33 +0200 Subject: [PATCH 36/45] Change order of switching user/group to group/user because of necessary permissions --- src/AppserverIo/Appserver/Core/Server.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index 7608f183a..eccf20ce2 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -597,18 +597,21 @@ protected function switchProcessUser() } } - // As we should only change user and group AFTER we made all chown and chgrp changes we will do it here - // after collecting if we are able to - if ($userChangeable) { + // As we should only change user and group AFTER we made all chown and chgrp + // changes we will do it here after collecting if we are able to. - // change the user ID - posix_setuid($userId); - } + // ATTENTION: We first need to change the group, because we need to be root + // to do that. After that we can change the user also!!!!!!!!!!! if ($groupChangeable) { // change the group ID posix_setgid($groupId); } + if ($userChangeable) { + + // change the user ID + posix_setuid($userId); + } // log a message with the time needed for restart $this->getSystemLogger()->info( From 9a7a303adc95cc3bbe7b98f90524e75298bd9fb6 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 11 May 2015 10:02:42 +0200 Subject: [PATCH 37/45] Raise number of executing jobs from 50 to 200 to optimize MQ speed --- src/AppserverIo/Appserver/MessageQueue/QueueWorker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index 5cffaedbc..fe2d82cec 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -293,7 +293,7 @@ public function run() $inQueue = sizeof($jobsExecuting); // we only process 50 jobs in parallel - if ($inQueue < 50) { + if ($inQueue < 200) { // start the job and add it to the internal array $jobsExecuting[$message->getMessageId()] = new Job(clone $message, $application); @@ -302,7 +302,7 @@ public function run() } else { // log a message that queue is actually full - $application->getInitialContext()->getSystemLogger()->debug( + $application->getInitialContext()->getSystemLogger()->info( sprintf('Job queue full - (%d jobs/%d msg wait)', $inQueue, sizeof($messages)) ); } From 884a7287ec57b1add6859bc78544f11f39966697 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Mon, 11 May 2015 10:05:45 +0200 Subject: [PATCH 38/45] Update code comment --- src/AppserverIo/Appserver/MessageQueue/QueueWorker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php index fe2d82cec..6650267c6 100644 --- a/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php +++ b/src/AppserverIo/Appserver/MessageQueue/QueueWorker.php @@ -292,7 +292,7 @@ public function run() // count messages in queue $inQueue = sizeof($jobsExecuting); - // we only process 50 jobs in parallel + // we only process 200 jobs in parallel if ($inQueue < 200) { // start the job and add it to the internal array $jobsExecuting[$message->getMessageId()] = new Job(clone $message, $application); From daad0dc82c71010a3030218d2bc749d9fa112ae4 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Mon, 11 May 2015 16:55:30 +0200 Subject: [PATCH 39/45] refactored inital permission change of log files --- src/AppserverIo/Appserver/Core/Server.php | 50 +++++------------------ 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/src/AppserverIo/Appserver/Core/Server.php b/src/AppserverIo/Appserver/Core/Server.php index eccf20ce2..4ffa3bf2c 100644 --- a/src/AppserverIo/Appserver/Core/Server.php +++ b/src/AppserverIo/Appserver/Core/Server.php @@ -534,8 +534,7 @@ protected function switchProcessUser() // if we're on a OS (not Windows) that supports POSIX we have // to change the configured user/group for security reasons. if (!extension_loaded('posix')) { - - // Log that we were not able to change the user + // log that we were not able to change the user $this->getSystemLogger()->info( "Could not change user due to missing POSIX extension" ); @@ -543,72 +542,45 @@ protected function switchProcessUser() } // init API service to use - $service = $this->newService('AppserverIo\Appserver\Core\Api\ContainerService'); + $containerService = $this->newService('AppserverIo\Appserver\Core\Api\ContainerService'); - // Check for the existence of a user + // check for the existence of a user $user = $this->getSystemConfiguration()->getParam('user'); $userChangeable = false; if (!empty($user)) { - - // Get the user id and set it accordingly + // get the user id, set it accordingly and check if it is usable for a user switch $userId = posix_getpwnam($user)['uid']; - - // Did we get something useful? if (is_int($userId)) { - - // check if deploy dir exists - if (is_dir(new \DirectoryIterator($logDir = $service->getLogDir()))) { - // init file iterator on deployment directory - $fileIterator = new \FilesystemIterator($logDir); - // Iterate through all phar files and extract them to tmp dir - foreach (new \RegexIterator($fileIterator, '/^.*\\.log$/') as $logFile) { - chown($logFile, $userId); - } - } - - // Tell them that we are able to change the user + // tell them that we are able to change the user $userChangeable = true; } } - // Check for the existence of a group + // check for the existence of a group $group = $this->getSystemConfiguration()->getParam('group'); $groupChangeable = false; if (!empty($group)) { - - // Get the user id and set it accordingly + // get the user id, set it accordingly and check if it is usable for a group switch $groupId = posix_getgrnam($group)['gid']; - - // Did we get something useful? if (is_int($groupId)) { - - // check if deploy dir exists - if (is_dir(new \DirectoryIterator($logDir = $service->getLogDir()))) { - // init file iterator on deployment directory - $fileIterator = new \FilesystemIterator($logDir); - // Iterate through all phar files and extract them to tmp dir - foreach (new \RegexIterator($fileIterator, '/^.*\\.log$/') as $logFile) { - chgrp($logFile, $groupId); - } - } - - // Tell them we are able to change the group + // tell them we are able to change the group $groupChangeable = true; } } + // do the actual file permission switching + $containerService->setUserRights(new \SplFileInfo($containerService->getLogDir())); + // As we should only change user and group AFTER we made all chown and chgrp // changes we will do it here after collecting if we are able to. // ATTENTION: We first need to change the group, because we need to be root // to do that. After that we can change the user also!!!!!!!!!!! if ($groupChangeable) { - // change the group ID posix_setgid($groupId); } if ($userChangeable) { - // change the user ID posix_setuid($userId); } From 5a896c8b8ae5f8db59f5bbf225e437e69b49df14 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Fri, 22 May 2015 17:19:14 +0200 Subject: [PATCH 40/45] Cherry Pick setup error from master branch --- server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.php b/server.php index 76a2f6abc..cbdb1bc66 100755 --- a/server.php +++ b/server.php @@ -194,10 +194,10 @@ // get defined user and group from configuration $user = Setup::getValue(SetupKeys::USER); $group = Setup::getValue(SetupKeys::GROUP); - // replace user to be same as group in configuration file + // replace user to be same as user in configuration file file_put_contents($configurationFileName, preg_replace( $configurationUserReplacePattern, - '${1}' . $group, + '${1}' . $user, file_get_contents($configurationFileName) )); // set correct file permissions for configurations From b024d334a21c3415996320bca6f13fd375d3b047 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Tue, 26 May 2015 15:13:58 +0200 Subject: [PATCH 41/45] Set correct code from 500 to 404 for requesting an application that not exists --- .../Appserver/ServletEngine/AbstractServletEngine.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/ServletEngine/AbstractServletEngine.php b/src/AppserverIo/Appserver/ServletEngine/AbstractServletEngine.php index 3400a5c14..28d0f21e2 100644 --- a/src/AppserverIo/Appserver/ServletEngine/AbstractServletEngine.php +++ b/src/AppserverIo/Appserver/ServletEngine/AbstractServletEngine.php @@ -96,7 +96,14 @@ protected function findRequestedApplication(RequestContextInterface $requestCont } // if we did not find anything we should throw a bad request exception - throw new BadRequestException(sprintf('Can\'t find application for URL %s%s', $requestContext->getServerVar(ServerVars::HTTP_HOST), $requestContext->getServerVar(ServerVars::X_REQUEST_URI))); + throw new BadRequestException( + sprintf( + 'Can\'t find application for URL %s%s', + $requestContext->getServerVar(ServerVars::HTTP_HOST), + $requestContext->getServerVar(ServerVars::X_REQUEST_URI) + ), + 404 + ); } /** From 4ffe35aba607b39a7f2e137f279a5b5ea5e9c6a0 Mon Sep 17 00:00:00 2001 From: Tim Wagner Date: Tue, 26 May 2015 15:27:01 +0200 Subject: [PATCH 42/45] Update CHANGELOG.md + switch to 1.0.6 release --- CHANGELOG.md | 11 +++++++++++ UPGRADE-1.0.6.md | 3 +++ build.default.properties | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 UPGRADE-1.0.6.md diff --git a/CHANGELOG.md b/CHANGELOG.md index fc23335e0..c9059dbbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# Version 1.0.6 + +## Bugfixes + +* Fixed [#828](https://github.com/appserver-io/appserver/issues/828) - Unknown application causes 500 instead of 404 +* Fixed [#829](https://github.com/appserver-io/appserver/issues/829) - Setup with parameter -s=dev set's invalid user on Mac OS X + +## Features + +* None + # Version 1.0.5 ## Bugfixes diff --git a/UPGRADE-1.0.6.md b/UPGRADE-1.0.6.md new file mode 100644 index 000000000..cbd6376f8 --- /dev/null +++ b/UPGRADE-1.0.6.md @@ -0,0 +1,3 @@ +# Upgrade from 1.0.5 to 1.0.6 + +Updating from 1.0.5 to 1.0.6 doesn't have any impacts. Please read the apropriate UPGRADE-1.x.x files for updates from older versions to 1.0.5. diff --git a/build.default.properties b/build.default.properties index e0c174cae..20bfcc01c 100644 --- a/build.default.properties +++ b/build.default.properties @@ -8,7 +8,7 @@ #-------------------------------------------------------------------------------- # ---- Module Release Settings -------------------------------------------------- -release.version = 1.0.5 +release.version = 1.0.6 release.name = Iron Horse # ---- PHPCPD Settings ---------------------------------------------------------- From befa30350cd4e4dcc5ac0864cc9b9a4b401c8432 Mon Sep 17 00:00:00 2001 From: wick-ed Date: Tue, 16 Jun 2015 18:50:22 +0200 Subject: [PATCH 43/45] opened up servers to be open by default --- CHANGELOG.md | 2 +- src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php | 4 ++-- .../Appserver/Meta/Composer/Script/SetupKeys.php | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9059dbbc..c7a2f65ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ ## Features -* None +* Closed [#844](https://github.com/appserver-io/appserver/issues/844) - Default server reachability should be all IPs # Version 1.0.5 diff --git a/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php b/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php index 05701b790..e3c271f47 100644 --- a/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php +++ b/src/AppserverIo/Appserver/Meta/Composer/Script/Setup.php @@ -67,10 +67,10 @@ class Setup SetupKeys::CONTAINER_SERVER_WORKER_ACCEPT_MIN => 3, SetupKeys::CONTAINER_SERVER_WORKER_ACCEPT_MAX => 8, SetupKeys::CONTAINER_HTTP_WORKER_NUMBER => 16, - SetupKeys::CONTAINER_HTTP_HOST => SetupKeys::DEFAULT_HOST, + SetupKeys::CONTAINER_HTTP_HOST => SetupKeys::OPEN_HOST, SetupKeys::CONTAINER_HTTP_PORT => 9080, SetupKeys::CONTAINER_HTTPS_WORKER_NUMBER => 16, - SetupKeys::CONTAINER_HTTPS_HOST => SetupKeys::DEFAULT_HOST, + SetupKeys::CONTAINER_HTTPS_HOST => SetupKeys::OPEN_HOST, SetupKeys::CONTAINER_HTTPS_PORT => 9443, SetupKeys::CONTAINER_MESSAGE_QUEUE_WORKER_NUMBER => 4, SetupKeys::CONTAINER_MESSAGE_QUEUE_HOST => SetupKeys::DEFAULT_HOST, diff --git a/src/AppserverIo/Appserver/Meta/Composer/Script/SetupKeys.php b/src/AppserverIo/Appserver/Meta/Composer/Script/SetupKeys.php index b1316a074..b30236235 100644 --- a/src/AppserverIo/Appserver/Meta/Composer/Script/SetupKeys.php +++ b/src/AppserverIo/Appserver/Meta/Composer/Script/SetupKeys.php @@ -151,6 +151,13 @@ class SetupKeys */ const DEFAULT_HOST = '127.0.0.1'; + /** + * Host values which allow an open access to the server. + * + * @var string + */ + const OPEN_HOST = '0.0.0.0'; + /** * Configuration key for 'appserver.php.version'. * From 604148a8b9b13a4c9d00960b27c8ea3bbe0b6db6 Mon Sep 17 00:00:00 2001 From: Johann Zelger Date: Fri, 3 Jul 2015 12:27:33 +0200 Subject: [PATCH 44/45] fixed weak digest_alk on cert generation --- src/AppserverIo/Appserver/Core/Api/ContainerService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppserverIo/Appserver/Core/Api/ContainerService.php b/src/AppserverIo/Appserver/Core/Api/ContainerService.php index 6db7f6a84..0c693637a 100644 --- a/src/AppserverIo/Appserver/Core/Api/ContainerService.php +++ b/src/AppserverIo/Appserver/Core/Api/ContainerService.php @@ -81,7 +81,7 @@ public function createSslCertificate(\SplFileInfo $certificate) default: // on all other use a standard configuration $configargs = array( - 'digest_alg' => 'md5', + 'digest_alg' => 'sha256', 'x509_extensions' => 'v3_ca', 'req_extensions' => 'v3_req', 'private_key_bits' => 2048, From 39c084a0bf6bdc7b4e9927dbc75206d032bca4c4 Mon Sep 17 00:00:00 2001 From: Bernhard Wick Date: Wed, 8 Jul 2015 13:52:00 +0200 Subject: [PATCH 45/45] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7a2f65ab..afe567d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,13 @@ ## Bugfixes +* Fixed [#798](https://github.com/appserver-io/appserver/issues/798) - Installation on Ubuntu Gnome 15.04 not possible * Fixed [#828](https://github.com/appserver-io/appserver/issues/828) - Unknown application causes 500 instead of 404 * Fixed [#829](https://github.com/appserver-io/appserver/issues/829) - Setup with parameter -s=dev set's invalid user on Mac OS X +* Fixes [#836](https://github.com/appserver-io/appserver/issues/836) - Appserver.xml does contain invalid host attributes +* Fixed [#839](https://github.com/appserver-io/appserver/issues/839) - appserver and appserver-watcher Provides collision +* Fixed [#842](https://github.com/appserver-io/appserver/issues/842) - Cannot use Traits +* Fixed [#847](https://github.com/appserver-io/appserver/issues/847) - Webserver based authentication is missing "realm" ## Features pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy