diff --git a/ProcessMaker/Models/ScriptDockerNayraTrait.php b/ProcessMaker/Models/ScriptDockerNayraTrait.php index 8a2aa83625..dacd103477 100644 --- a/ProcessMaker/Models/ScriptDockerNayraTrait.php +++ b/ProcessMaker/Models/ScriptDockerNayraTrait.php @@ -11,9 +11,9 @@ use ProcessMaker\Exception\ScriptException; use ProcessMaker\Facades\Docker; use ProcessMaker\ScriptRunners\Base; -use RuntimeException; -use Psr\Container\NotFoundExceptionInterface; use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use RuntimeException; use UnexpectedValueException; /** @@ -21,7 +21,6 @@ */ trait ScriptDockerNayraTrait { - private $schema = 'http'; /** @@ -45,13 +44,16 @@ public function handleNayraDocker(string $code, array $data, array $config, $tim 'timeout' => $timeout, ]; $body = json_encode($params); - $servers = self::getNayraAddresses(); - if (!$servers) { + + if (!$this->hasConfiguredNayraRestApiHost() && !self::getNayraAddresses()) { $this->bringUpNayra(); } + $baseUrl = $this->getNayraInstanceUrl(); $url = $baseUrl . '/run_script'; - $this->ensureNayraServerIsRunning($baseUrl); + if (!$this->hasConfiguredNayraRestApiHost()) { + $this->ensureNayraServerIsRunning($baseUrl); + } $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); @@ -62,8 +64,8 @@ public function handleNayraDocker(string $code, array $data, array $config, $tim 'Content-Length: ' . strlen($body), ]); $result = curl_exec($ch); - curl_close($ch); $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); if ($httpStatus !== 200) { $result .= ' HTTP Status: ' . $httpStatus; $result .= ' URL: ' . $url; @@ -75,15 +77,31 @@ public function handleNayraDocker(string $code, array $data, array $config, $tim ]); throw new ScriptException($result); } + return $result; } private function getNayraInstanceUrl() { + if ($this->hasConfiguredNayraRestApiHost()) { + return $this->getConfiguredNayraRestApiHost(); + } + $servers = self::getNayraAddresses(); + return $this->schema . '://' . $servers[0] . ':' . $this->getNayraPort(); } + private function hasConfiguredNayraRestApiHost(): bool + { + return $this->getConfiguredNayraRestApiHost() !== ''; + } + + private function getConfiguredNayraRestApiHost(): string + { + return rtrim((string) config('app.nayra_rest_api_host'), '/'); + } + private function getDockerLogs($instanceName) { $docker = Docker::command(); @@ -92,6 +110,7 @@ private function getDockerLogs($instanceName) if ($status) { return 'Error getting logs from Nayra Docker: ' . implode("\n", $logs); } + return implode("\n", $logs); } @@ -106,6 +125,10 @@ private function ensureNayraServerIsRunning(string $url) { $header = @get_headers($url); if (!$header) { + if ($this->hasConfiguredNayraRestApiHost()) { + throw new ScriptException('Could not connect to configured Nayra REST API host'); + } + $this->bringUpNayra(true); } } @@ -206,7 +229,7 @@ private static function findNayraAddresses($docker, $instanceName, $times): bool . ($nayraDockerNetwork ? "'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'" : "'{{ .NetworkSettings.IPAddress }}'" - ) + ) . " {$instanceName}_nayra 2>/dev/null", $output, $status @@ -217,6 +240,7 @@ private static function findNayraAddresses($docker, $instanceName, $times): bool } if ($ip) { self::setNayraAddresses([$ip]); + return true; } } @@ -280,6 +304,7 @@ public static function clearNayraAddresses() private static function isCacheArrayStore(): bool { $cacheDriver = Cache::getFacadeRoot()->getStore(); + return $cacheDriver instanceof ArrayStore; } diff --git a/tests/unit/ProcessMaker/Models/ScriptDockerNayraTraitTest.php b/tests/unit/ProcessMaker/Models/ScriptDockerNayraTraitTest.php new file mode 100644 index 0000000000..c6425f870c --- /dev/null +++ b/tests/unit/ProcessMaker/Models/ScriptDockerNayraTraitTest.php @@ -0,0 +1,91 @@ +instance('config', new ConfigRepository([ + 'app' => [ + 'nayra_rest_api_host' => '', + 'nayra_port' => 8080, + ], + ])); + + $this->cachePath = sys_get_temp_dir() . '/processmaker-nayra-test-cache-' . uniqid('', true); + Cache::swap(new CacheRepository(new FileStore(new Filesystem(), $this->cachePath))); + } + + protected function tearDown(): void + { + TestNayraScriptRunner::clearNayraAddresses(); + (new Filesystem())->deleteDirectory($this->cachePath); + Facade::clearResolvedInstances(); + Facade::setFacadeApplication(null); + Container::setInstance(null); + + parent::tearDown(); + } + + public function testConfiguredNayraRestApiHostIsUsedInsteadOfCachedDockerAddress(): void + { + config([ + 'app.nayra_rest_api_host' => 'http://nayra-service:8080/', + 'app.nayra_port' => 8080, + ]); + TestNayraScriptRunner::setNayraAddresses(['172.18.0.5']); + + $this->assertSame( + 'http://nayra-service:8080', + $this->getNayraInstanceUrl() + ); + } + + public function testDockerAddressIsUsedWhenNayraRestApiHostIsNotConfigured(): void + { + config([ + 'app.nayra_rest_api_host' => '', + 'app.nayra_port' => 8081, + ]); + TestNayraScriptRunner::setNayraAddresses(['172.18.0.5']); + + $this->assertSame( + 'http://172.18.0.5:8081', + $this->getNayraInstanceUrl() + ); + } + + private function getNayraInstanceUrl(): string + { + $runner = new TestNayraScriptRunner(); + $reflection = new ReflectionClass($runner); + $method = $reflection->getMethod('getNayraInstanceUrl'); + + return $method->invoke($runner); + } +} + +class TestNayraScriptRunner +{ + use ScriptDockerNayraTrait; +}