Skip to content

Commit

Permalink
Merge c89168c into 970339b
Browse files Browse the repository at this point in the history
  • Loading branch information
blanchonvincent committed Sep 29, 2013
2 parents 970339b + c89168c commit 3ea7a47
Show file tree
Hide file tree
Showing 34 changed files with 1,745 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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
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
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
},
"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
76 changes: 76 additions & 0 deletions docs/remote-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# 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($configuration);
$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) !

## Tuning performance for production

See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
68 changes: 68 additions & 0 deletions src/ProxyManager/Factory/RemoteObject/Adapter/BaseAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?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
* @return string Service name
*/
abstract protected function assemble($wrappedClass, $method);

/**
* Build webservices client
* @return \Zend\Server\Client
*/
abstract public function getClient();
}
73 changes: 73 additions & 0 deletions src/ProxyManager/Factory/RemoteObject/Adapter/JsonRpc.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 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
*/
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;
}
$this->client = new Client($this->uri);

return $this->client;
}
}
73 changes: 73 additions & 0 deletions src/ProxyManager/Factory/RemoteObject/Adapter/Soap.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 Zend\Soap\Client;
use ProxyManager\Proxy\Exception\RemoteObjectException;

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

/**
* Rpc client building
* @param string $uri
*/
public function __construct($uri)
{
if (! class_exists('Zend\Soap\Client')) {
throw new RemoteObjectException('Soap adapter does not exists. Please install zend-soap package.');
}
if (empty($uri)) {
throw new RemoteObjectException('Soap WSDL is required');
}
parent::__construct($uri);
}

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

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

return $this->client;
}
}
Loading

0 comments on commit 3ea7a47

Please sign in to comment.