Skip to content

Commit

Permalink
Prep 2.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
belgattitude committed Oct 9, 2017
1 parent 6bd0b85 commit 84c84f9
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ return PhpCsFixer\Config::create()
'blank_line_before_return' => true,
'cast_spaces' => true,
'class_definition' => ['singleLine' => true],
'concat_space' => ['spacing' => "none"], // Different from symfony (none)
'concat_space' => ['spacing' => "none"],
'declare_equal_normalize' => true,
'function_typehint_space' => true,
'hash_to_slash_comment' => true,
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 2.4.0 (2017-09-19)

### Added

- Added support for basic authentication in connection servlet_address.

```php
<?php
$ba = new BridgeAdapter([
'servlet_address' => 'http://user:pass@localhost:8080/MyJavaBridge/servlet.phpjavabridge'
]);
```

- Added `AuthenticationException` (ConnectionException).

- Logger now logs java exceptions (NoSuchProcedureException,... at error level).

### Fixed

- Notice and warnings when a BrokenConnection is encountered.

## 2.3.0 (2017-09-19)

### Improved
Expand Down
12 changes: 7 additions & 5 deletions doc/bridge_connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use Soluble\Japha\Bridge\Adapter as BridgeAdapter;
use Soluble\Japha\Bridge\Exception as BridgeException;

$options = [
'servlet_address' => 'localhost:8080/MyJavaBridge/servlet.phpjavabridge'
'servlet_address' => 'http://localhost:8080/MyJavaBridge/servlet.phpjavabridge'
];

try {
Expand All @@ -38,11 +38,11 @@ The `Soluble\Japha\Bridge\Adapter` constructor requires `$options`, an associati

| Parameter | Description |
|------------------|------------------------------------------|
|`servlet_address` | Servlet address: &lt;host&gt;:&lt;port&gt;/&lt;uri&gt; |
|`driver` | (Optional) defaults to `pjb62` driver implementation. |
|`servlet_address` | In the form: `http(s)://<host>:<port>/<context_uri>/servlet.phpjavabridge` |

!!! tip
The `servlet_address` &lt;uri&gt; should ends with the **'servlet.phpjavabridge'** file,
i.e: 'localhost:8080/path/servlet.phpjavabridge'.
Since v2.4.0, you can also provide basic auth in the `servlet_address`, i.e.
`http://user:password@localhost:8083/JavaBridge/servlet.phpjavabridge`.


| Advanced params | Description |
Expand All @@ -51,6 +51,7 @@ The `Soluble\Japha\Bridge\Adapter` constructor requires `$options`, an associati
|`java_recv_size` | Socket read buffer, by default `8192`. |
|`java_log_level` | To enable java side logging level, by default `null`. |
|`force_simple_xml_parser` | By default `false`: force the Use the php xml parser instead of native xml_parser(). |
|`driver` | Defaults to `pjb62` driver implementation. |
|`java_prefer_values` | By default `true`, see warning below. |


Expand Down Expand Up @@ -106,6 +107,7 @@ During initialization with the BridgeAdapter, the following exceptions could hap
| ExceptionClass | Description |
|------------------------------------------|-----------------------------|
|`Soluble\Japha\Bridge\Exception\ConnectionException` | Server not available *(network port is unreachable)* |
|`Soluble\Japha\Bridge\Exception\AuthenticationException` | Invalid credentials given in basic auth *(check config)* |
|`Soluble\Japha\Bridge\Exception\ConfigurationException` | Invalid connection parameter *(check config)* |
|`Soluble\Japha\Bridge\Exception\UnsupportedDriverException` | Specified driver is not supported *(check config)* |
|`Soluble\Japha\Bridge\Exception\InvalidArgumentException` | Invalid argument in constructor *(check usage)* |
Expand Down
3 changes: 3 additions & 0 deletions doc/language_exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ the Java/JVM exception, you can use the following methods:
For example: java.lang.java.lang.NoSuchMethodException, ...
- `JavaException::getStackTrace()` will give you the JVM stacktrace.

!!! tip
From version 2.4.0, JavaExceptions are logged. See how to inject
a PSR-3 logger in the [bridge_connection section](./bridge_connection.md)

```php
<?php
Expand Down
3 changes: 1 addition & 2 deletions src/Soluble/Japha/Bridge/Driver/Pjb62/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,7 @@ public function begin(string $name, array $st): void
default:
$this->protocol->handler->shutdownBrokenConnection(
sprintf(
'Parser error, check the backend for details, $name: %s, '.
'$st params: %s',
'Parser error, check the backend for details, "$name": %s, "$st": %s',
$name,
json_encode($st)
)
Expand Down
64 changes: 53 additions & 11 deletions src/Soluble/Japha/Bridge/Driver/Pjb62/PjbProxyClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Soluble\Japha\Bridge\Driver\Pjb62;

use Monolog\Logger;
use Soluble\Japha\Bridge\Exception;
use Soluble\Japha\Interfaces;
use Soluble\Japha\Bridge\Driver\ClientInterface;
Expand All @@ -26,6 +27,8 @@ class PjbProxyClient implements ClientInterface
*/
protected static $instance;

protected static $unregistering = false;

/**
* @var array
*/
Expand Down Expand Up @@ -227,6 +230,8 @@ protected function loadClient(): void
* Return Pjb62 internal client.
*
* @return Client
*
* @throws Exception\BrokenConnectionException
*/
public static function getClient(): Client
{
Expand Down Expand Up @@ -298,8 +303,6 @@ public function invokeMethod(?Interfaces\JavaType $object = null, string $method
*/
public function inspect(Interfaces\JavaType $object): string
{
//$client = self::getClient();
//return $client->invokeMethod(0, "inspect", array($object));
return self::getClient()->invokeMethod(0, 'inspect', [$object]);
}

Expand Down Expand Up @@ -478,8 +481,6 @@ public function getOptions(): ArrayObject
/**
* Return specific option.
*
* @param $name
*
* @return mixed
*/
public function getOption(string $name)
Expand All @@ -491,17 +492,57 @@ public function getOption(string $name)
return $this->options[$name];
}

public function getLogger(): LoggerInterface
{
return $this->logger;
}

/**
* @throws Exception\BrokenConnectionException|Exception\AuthenticationException
*/
public static function unregisterAndThrowBrokenConnectionException(string $message = null, int $code = null): void
{
if (self::$instance !== null) {
$message = $message ?? 'undefined messsage';

switch ($code) {
case 401:
$exception = new Exception\AuthenticationException(sprintf(
'Java bridge authentication failure: code: %s',
$code
));
break;
default:
$exception = new Exception\BrokenConnectionException(sprintf(
'Java bridge broken connection: "%s" (code: %s)',
$message,
$code
));
}
try {
self::$instance->getLogger()->critical(sprintf(
'[soluble-japha] BrokenConnectionException to "%s": "%s" (code: "%s")',
self::$instance->getOption('servlet_address'),
$message,
$code ?? '?'
));
} catch (\Throwable $e) {
// discard logger errors
}

self::unregisterInstance();
throw $exception;
}
}

/**
* Clean up PjbProxyClient instance.
*/
public static function unregisterInstance(): void
{
if (self::$client !== null) {
// TODO check with sessions
/*
if (session_id()) {
session_write_close();
}*/
if (!self::$unregistering && self::$client !== null) {
self::$unregistering = true;

if (self::$client->preparedToSendBuffer) {
self::$client->sendBuffer .= self::$client->preparedToSendBuffer;
}
Expand All @@ -517,7 +558,7 @@ public static function unregisterInstance(): void
// ADDED AN IF TO CHECK THE CHANNEL In CASE OF
//
if (isset(self::$client->protocol->handler->channel) &&
false === strpos(get_class(self::getClient()->protocol->handler->channel), '/EmptyChannel/')) {
false === strpos(get_class(self::getClient()->protocol->handler->channel), '/EmptyChannel/')) {
try {
self::$client->protocol->keepAlive();
} catch (\Throwable $e) {
Expand All @@ -528,6 +569,7 @@ public static function unregisterInstance(): void
self::$client = null;
self::$instance = null;
self::$instanceOptionsKey = null;
self::$unregistering = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,25 @@ protected function getExceptionFromResult(Pjb62\Exception\JavaException $result)
$message,
$cause,
$stackTrace,
$javaExceptionClass,
$javaExceptionClass,
$code,
$driverException,
null
);

$this->logException($e, $exceptionClass);

return $e;
}

protected function logException(\Throwable $e, string $exceptionClass): void
{
$this->logger->error(sprintf(
'[soluble-japha] Encountered exception %s: %s, code %s (%s)',
$exceptionClass,
$e->getMessage(),
$e->getCode() ?? '?',
get_class($e)
));
}
}
33 changes: 22 additions & 11 deletions src/Soluble/Japha/Bridge/Driver/Pjb62/SimpleHttpTunnelHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ public function createChannel()
$this->createSimpleChannel();
}

public function shutdownBrokenConnection(string $msg = ''): void
public function shutdownBrokenConnection(string $msg = '', int $code = null): void
{
fclose($this->socket);
$this->dieWithBrokenConnection($msg);
if (is_resource($this->socket)) {
fclose($this->socket);
}
PjbProxyClient::unregisterAndThrowBrokenConnectionException($msg, $code);
}

/**
Expand Down Expand Up @@ -161,7 +163,9 @@ public function read(int $size): string
$this->parseHeaders();
}

if (isset($this->headers['http_error'])) {
$http_error = $this->headers['http_error'] ?? null;

if ($http_error !== null) {
$str = null;
if (isset($this->headers['transfer_chunked'])) {
$str = $this->fread($this->java_recv_size);
Expand All @@ -176,7 +180,12 @@ public function read(int $size): string
$str = fread($this->socket, $this->java_recv_size);
}
$str = ($str === false || $str === null) ? '' : $str;
$this->shutdownBrokenConnection($str);

if ($http_error === 401) {
$this->shutdownBrokenConnection('Authentication exception', 401);
} else {
$this->shutdownBrokenConnection($str);
}
}

$response = $this->fread($this->java_recv_size);
Expand Down Expand Up @@ -233,22 +242,26 @@ public function write(string $data): ?int
if ($count === false) {
$this->shutdownBrokenConnection('Cannot write to socket, broken connection handle');
}
$flushed = fflush($this->socket);
$flushed = @fflush($this->socket);
if ($flushed === false) {
$this->shutdownBrokenConnection('Cannot flush to socket, broken connection handle');
}

return (int) $count;
}

protected function parseHeaders()
protected function parseHeaders(): void
{
$this->headers = [];

$line = trim(fgets($this->socket, $this->java_recv_size));
$res = @fgets($this->socket, $this->java_recv_size);
if ($res === false) {
$this->shutdownBrokenConnection('Cannot parse headers, socket cannot be read.');
}
$line = trim($res);
$ar = explode(' ', $line);
$code = ((int) $ar[1]);
if ($code != 200) {
if ($code !== 200) {
$this->headers['http_error'] = $code;
}
while ($str = trim(fgets($this->socket, $this->java_recv_size))) {
Expand Down Expand Up @@ -293,8 +306,6 @@ protected function parseHeaders()
*/
protected function getSimpleChannel()
{
// Originally bug found in Pjb
//return new ChunkedSocketChannel($this->socket, $this->protocol, $this->host);
return new ChunkedSocketChannel($this->socket, $this->host, $this->java_recv_size, $this->java_send_size);
}

Expand Down
18 changes: 12 additions & 6 deletions src/Soluble/Japha/Bridge/Driver/Pjb62/SocketChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,23 @@ public function fwrite(string $data): ?int

public function fread(int $size): ?string
{
$read = fread($this->peer, $size);
$read = @fread($this->peer, $size);
if ($read === false) {
PjbProxyClient::unregisterInstance();
throw new BrokenConnectionException('Broken socket communication with the php-java-bridge (read)');
PjbProxyClient::unregisterAndThrowBrokenConnectionException(
sprintf(
'Broken socket communication with the php-java-bridge while reading socket (%s).',
__METHOD__
)
);
} else {
return $read;
}

return $read;
}

public function shutdownBrokenConnection(?string $msg = ''): void
{
fclose($this->peer);
if (is_resource($this->peer)) {
fclose($this->peer);
}
}
}
19 changes: 4 additions & 15 deletions src/Soluble/Japha/Bridge/Driver/Pjb62/SocketHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@

namespace Soluble\Japha\Bridge\Driver\Pjb62;

use Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException;

class SocketHandler
{
/**
Expand Down Expand Up @@ -101,24 +99,15 @@ public function keepAlive(): void
$this->channel->keepAlive();
}

public function dieWithBrokenConnection(string $msg = ''): void
public function shutdownBrokenConnection(string $msg = '', int $code = null): void
{
if ($msg === '') {
$msg = 'Unkown error: please see back end log for detail';
}
$msg = $msg ?? 'Broken connection: Unkown error, please see back end log for detail';

// Log error
$client = $this->protocol->getClient();
$client->getLogger()->critical("[soluble-japha] $msg\" (".__METHOD__.')');

$client->getLogger()->critical("[soluble-japha] Broken connection: $msg, check the backend log for details\" (".__METHOD__.')');

PjbProxyClient::unregisterInstance();
throw new BrokenConnectionException("Broken connection: $msg, check the backend log for details");
}

public function shutdownBrokenConnection(string $msg = ''): void
{
$this->channel->shutdownBrokenConnection();
$this->dieWithBrokenConnection($msg);
PjbProxyClient::unregisterAndThrowBrokenConnectionException($msg, $code);
}
}
Loading

0 comments on commit 84c84f9

Please sign in to comment.