Skip to content

Commit

Permalink
Merge 0d776b0 into 970339b
Browse files Browse the repository at this point in the history
  • Loading branch information
blanchonvincent committed Sep 30, 2013
2 parents 970339b + 0d776b0 commit c1eec25
Show file tree
Hide file tree
Showing 46 changed files with 2,208 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ php:

before_script:
- composer self-update
- composer update --prefer-source --dev
- composer update --prefer-source; composer install --dev --prefer-source;

script:
- ./vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml --exclude-group Functional,Performance
- ./vendor/bin/phpunit --group=Functional
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.4' ]; then echo 'starting PHP server on port 8080'; php -S localhost:8080 -t tests/server/ & fi"
- ./vendor/bin/phpunit ./tests/language-feature-scripts/
- php -n ./vendor/bin/phpunit --group=Performance
- ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,25 @@ This feature [yet to be planned](https://github.com/Ocramius/ProxyManager/issues
A remote object proxy is an object that is located on a different system, but is used as if it was available locally.
There's various possible remote proxy implementations, which could be based on xmlrpc/jsonrpc/soap/dnode/etc.

This feature [yet to be planned](https://github.com/Ocramius/ProxyManager/issues/7).
Three adapters are available by default : XmlRpc, JsonRpc & Soap. Custom adapters must implement ProxyManager\Factory\RemoteObject\AdapterInterface.

```php
interface FooServiceInterface
{
public function foo();
}

$factory = new \ProxyManager\Factory\RemoteObjectFactory();
$adapter = new \ProxyManager\Factory\RemoteObject\Adapter\XmlRpc(
'http://127.0.0.1/xmlrpc.php' // your XmlRpc host
);

// proxy is your distant implementation
$proxy = $factory->createProxy('FooServiceInterface', $adapter);
```

See the [complete documentation about remote objects](https://github.com/Ocramius/ProxyManager/tree/master/docs/remote-object.md)
in the `docs/` directory.

## Contributing

Expand Down
10 changes: 8 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@
"phpunit/phpunit": ">=3.7",
"phpmd/phpmd": "1.4.*",
"squizlabs/php_codesniffer": "1.4.*",
"satooshi/php-coveralls": "~0.6"
"satooshi/php-coveralls": "~0.6",
"zendframework/zend-json": "2.*",
"zendframework/zend-xmlrpc": "2.*",
"zendframework/zend-soap": "2.*"
},
"suggest": {
"zendframework/zend-stdlib": "To use the hydrator proxy",
"ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects"
"ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
"zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)",
"zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
"zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)"
},
"autoload": {
"psr-0": {
Expand Down
168 changes: 168 additions & 0 deletions docs/remote-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Remote Object Proxy

The remote object implementation is a mechanism that enables an local object to control an other object on an other server.
Each call method on the local object will do a network call to get information or execute operations on the remote object.

## What is remote object proxy ?

A remote object is based on an interface. The remote interface defines the API that a consumer can call. This interface
must be implemented both by the client and the RPC server.

## Usage examples

RPC server side code :

```php
interface FooServiceInterface
{
public function foo();
}

class Foo implements FooServiceInterface
{
/**
* Foo function
* @return string
*/
public function foo()
{
return 'bar remote';
}
}

$server = new Zend\XmlRpc\Server();
$server->setClass('Foo', 'FooServiceInterface'); // my FooServiceInterface implementation
$server->handle();
```

Client side code (proxy) :

```php
interface FooServiceInterface
{
public function foo();
}

$factory = new \ProxyManager\Factory\RemoteObjectFactory();
$adapter = new \ProxyManager\Factory\RemoteObject\Adapter\XmlRpc(
'http://127.0.0.1/xmlrpc.php'
);

$proxy = $factory->createProxy('FooServiceInterface', $adapter);

var_dump($proxy->foo()); // "bar remote"
```

Three adapters are available by default : `ProxyManager\Factory\RemoteObject\Adapter\XmlRpc`, `ProxyManager\Factory\RemoteObject\Adapter\JsonRpc` & `ProxyManager\Factory\RemoteObject\Adapter\Soap`. Custom adapter must implement `ProxyManager\Factory\RemoteObject\AdapterInterface` :

```php
interface AdapterInterface
{
/**
* Call remote object
*
* @param string $wrappedClass
* @param string $method
* @param array $params
*/
public function call($wrappedClass, $method, array $params = array());
}
```

It is very easy to create your own implementation (Rest for example) !

## Adapter usages examples

* Example with JsonRpc adapter :

Json server side code :

```php
interface FooServiceInterface
{
public function foo();
}

class Foo implements FooServiceInterface
{
/**
* Foo function
* @return string
*/
public function foo()
{
return 'bar remote';
}
}

$server = new Zend\Json\Server\Server();
$server->setClass('Foo', 'FooServiceInterface'); // my FooServiceInterface implementation
$server->handle();
```

Client side code (proxy) :

```php
interface FooServiceInterface
{
public function foo();
}

$factory = new \ProxyManager\Factory\RemoteObjectFactory();
$adapter = new \ProxyManager\Factory\RemoteObject\Adapter\JsonRpc(
'http://127.0.0.1/jsonrpc.php'
);

$proxy = $factory->createProxy('FooServiceInterface', $adapter);

var_dump($proxy->foo()); // "bar remote"
```

* Example with Soap adapter :

Json server side code :

```php
interface FooServiceInterface
{
public function foo();
}

class Foo implements FooServiceInterface
{
/**
* Foo function
* @return string
*/
public function foo()
{
return 'bar remote';
}
}

$server = new Zend\Soap\Server(__DIR__ . '/soap.wsdl');
$server->setClass('Foo'); // my FooServiceInterface implementation
$server->handle();
```

Client side code (proxy) :

```php
interface FooServiceInterface
{
public function foo();
}

$factory = new \ProxyManager\Factory\RemoteObjectFactory();
$adapter = new \ProxyManager\Factory\RemoteObject\Adapter\Soap(
'http://127.0.0.1/soap.php'
);

$proxy = $factory->createProxy('FooServiceInterface', $adapter);

var_dump($proxy->foo()); // "bar remote"
```

## Tuning performance for production

See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
3 changes: 1 addition & 2 deletions src/ProxyManager/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ class Configuration
protected $classNameInflector;

/**
* @param bool $autoGenerateProxies
* @deprecated deprecated since version 0.5
*/
public function setAutoGenerateProxies($autoGenerateProxies)
public function setAutoGenerateProxies()
{
}

Expand Down
73 changes: 73 additions & 0 deletions src/ProxyManager/Factory/RemoteObject/Adapter/BaseAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ProxyManager\Factory\RemoteObject\Adapter;

use ProxyManager\Factory\RemoteObject\AdapterInterface;

/**
* Remote Object base adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
abstract class BaseAdapter implements AdapterInterface
{
/**
* URI of the webservice endpoint
* @var string
*/
protected $uri;

/**
* Constructor
* @param string $uri
*/
public function __construct($uri)
{
$this->uri = $uri;
}

/**
* {@inheritDoc}
*/
public function call($wrappedClass, $method, array $params = array())
{
$client = $this->getClient();
$serviceName = $this->assemble($wrappedClass, $method);

return $client->call($serviceName, $params);
}

/**
* Assembly of the service name will be used by the adapter
*
* @param string $wrappedClass
* @param string $method
*
* @return string Service name
*/
abstract protected function assemble($wrappedClass, $method);

/**
* Build webservices client
*
* @return \Zend\Server\Client
*/
abstract public function getClient();
}
77 changes: 77 additions & 0 deletions src/ProxyManager/Factory/RemoteObject/Adapter/JsonRpc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ProxyManager\Factory\RemoteObject\Adapter;

use Zend\Json\Server\Client;
use ProxyManager\Proxy\Exception\RemoteObjectException;

/**
* Remote Object JSON RPC adapter
*
* @author Vincent Blanchon <blanchon.vincent@gmail.com>
* @license MIT
*/
class JsonRpc extends BaseAdapter
{
/**
* JsonRpc client
* @var \Zend\Json\Server\Client
*/
private $client;

/**
* Rpc client building
*
* @param string $uri
*
* @throws \ProxyManager\Proxy\Exception\RemoteObjectException
*/
public function __construct($uri)
{
if (! class_exists('Zend\Json\Server\Client')) {
throw new RemoteObjectException('JsonRpc adapter does not exists. Please install zend-json package.');
}

if (empty($uri)) {
throw new RemoteObjectException('Webservices URI is required');
}

parent::__construct($uri);
}

/**
* {@inheritDoc}
*/
protected function assemble($wrappedClass, $method)
{
return $wrappedClass . '.' . $method;
}

/**
* {@inheritDoc}
*/
public function getClient()
{
if ($this->client) {
return $this->client;
}

return $this->client = new Client($this->uri);
}
}
Loading

0 comments on commit c1eec25

Please sign in to comment.