Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New soap engine #197

Merged
merged 50 commits into from Feb 22, 2019
Merged

New soap engine #197

merged 50 commits into from Feb 22, 2019

Conversation

veewee
Copy link
Contributor

@veewee veewee commented Oct 19, 2018

This enables #65: Abstract all ext-soap interactions to a generic driver system.

Abstract ext-soap into a "driver".
This PR makes it possible to create new drivers that do not depend on ext-soap.

Migrating

Change your code generation configuration

The code generation configuration has changed:

  • no wsdl methods anymore
  • no soapOptions methods anymore
  • no wsdl provider methods anymore
  • replaced the items above with engine methods (which is required):
<?php

use Phpro\SoapClient\CodeGenerator\Config\Config;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapEngineFactory;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;

return Config::create()
    ->setEngine(ExtSoapEngineFactory::fromOptions(
        ExtSoapOptions::defaults($wsdl, $soapOptions)
            ->withWsdlProvider($wsdlProvider)
            ->disableWsdlCache()
    ))
    // ....
;

As you can see, the WSDL and the soapOptions are moved to a new ExtSoapOptions class.
The ExtSoapEngineFactory will create a driver based on those soap options and will configure the ExtSoapClientHandle by default.
By providing this new driver system, it will be possible to generate code without ext-soap in the future.
For now, we only suppy the ext-soap driver.

Currently, we are using the default ExtSoapClientHandle in the engine.
You could however change this ext-soap handler to the HttPlugHandle by using the ExtSoapEngineFactory::fromOptionsWithHandler() method.
We've choosen to add the engine instead of the driver to the configuration for advanced future code generation features.

The code generation will work exactly as before. It will only use the new driver metadata implementation to detect methods and types.

Change your factories

Previously we used a lot of classes to get your client up and running.
We decided to remove both the ClientFactory and ClientBuilder and move the configuration to the generated factory.

Most of the configuration is related to the ext-soap SoapClient and is now moved to a new ExtSoapOptions class.
This new class is validated by a resolver. This way you will get a usefull error when you misconfigure one of the many soap options.
The newly introduced options class contains:

  • A wsdl
  • A wsdl provider mechanism
  • A set of default soap options
  • An easy way to configure / overwrite type maps
  • An easy way to configure classmaps

Based on the options, you can now create an ExtSoapDriver which is responsible for encoding / decoding soap requests.
The Handlers are still in charge of doing the actual HTTP requests.
Therefor, you'll have to configure following items directly on the Handler:

  • wsdl middleware
  • soap middleware

When both the driver and handler are configured, we can create a new engine.
Since there are a lot of possible configurations, an easy to use ExtSoapEngineFactory is added.
This one can be used as a shortcut to easily create the engine.

You can transform your builder like one of the examples below:

<?php

namespace App\Client;

use App\Client\Myclient;
use App\Classmap\Myclassmap;
use GuzzleHttp\Client;
use Phpro\SoapClient\Middleware\BasicAuthMiddleware;
use Phpro\SoapClient\Event\Subscriber\LogSubscriber;
use Phpro\SoapClient\Event\Subscriber\ValidatorSubscriber;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapEngineFactory;
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;
use Phpro\SoapClient\Soap\Handler\HttPlugHandle;
use Symfony\Component\EventDispatcher\EventDispatcher;

class MyclientFactory
{
    public static function factoryWithRegularExtSoapClient(string $wsdl): Myclient
    {
        $engine = ExtSoapEngineFactory::fromOptions(
            ExtSoapOptions::defaults($wsdl, $oapOptions)
              ->withWsdlProvider($wsdlProvider)
              ->withClassMap(Myclassmap::getCollection())
              ->withTypeMap($typeConverters) // You could also use getTypeMap and add / overwrite
        );

        $dispatcher = new EventDispatcher();
        $dispatcher->addSubscriber(new LogPlugin($logger));
        $dispatcher->addSubscriber(new ValidatorPlugin($validator));

        return new Myclient($engine, $dispatcher);
    }

    public static function factoryWithHttPlug(string $wsdl): Myclient
    {
        $httpHandle = HttPlugHandle::createForClient(Client::createWithConfig($httplugConfig));
        $httpHandle->addMiddleware(new BasicAuthMiddleware('user', 'password'));

        $engine = ExtSoapEngineFactory::fromOptionsWithHandler(
            ExtSoapOptions::defaults($wsdl, $oapOptions)
              ->withWsdlProvider($wsdlProvider)
              ->withClassMap(Myclassmap::getCollection())
              ->withTypeMap($typeConverters),
            $httpHandle
        );

        $dispatcher = new EventDispatcher();
        $dispatcher->addSubscriber(new LogSubscriber($logger));
        $dispatcher->addSubscriber(new ValidatorSubscriber($validator));

        return new Myclient($engine, $dispatcher);
    }
}

As you can see, you can still apply the exact same configuration as before:

  • A new ExtSoapOptions helper is added that makes it a lot easier to configure the ext-soap client.
    • the soapOptions are validated before the SoapClient is constructed. No more documentation lookups! :)
    • The classmap and typeconverters are now reusable in different drivers
    • You can still specify a wsdlProvider which will only be called once the SoapClient is initialized.
  • You now have to add middlewares directly on the HandleInterface
    • This way you cannot add middlewares to handlers that don't know how to deal with HTTP middleware.
  • The handler and engine are combined into an Engine which is injected into your client class.
  • The plugins now have to be enabled directly on the EventDispatcher.
    • You can create a new event dispatcher or use an existing one.

Remove your custom client -factories, -builders, -constructors

Since we removed both the ClientBuilder and Phpro\SoapClient\ClientFactoryInterface,
you will have to move the logic to the new client factory as described above.
Both the builder and clientFactory are permanently removed and will never come back again.

We also changed the constructor of the Client class. It now accepts an Engine and EventDispatcher.
If you changed the constructor signature, you will have to take a look at this as well.

Change namespace of old plugins

One of the first possible ways of extending the soap-client was by adding plugins. Since these plugins are actually event subscribers, it is a better idea to name them EventSubscribers. This is also less confusing with the http-plug plugins which are actually HTTP middlewares.
If you are manually assigning the LogPlugin or ValidatorPlugin, you might need to change these lines as well. The plugins are moved to following locations:

  • LogPlugin -> Phpro\SoapClient\Event\Subscriber\LogSubscriber
  • ValidatorPlugin -> Phpro\SoapClient\Event\Subscriber\ValidatorSubscriber

TODO

@veewee veewee added this to the 1.0.0 milestone Dec 6, 2018
@veewee veewee changed the title [WIP] New soap engine New soap engine Dec 6, 2018
@veewee veewee merged commit 50a06a2 into phpro:master Feb 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants