Skip to content

Commit

Permalink
Merge pull request #38 from veewee/service-location
Browse files Browse the repository at this point in the history
Add additional service selection criteria
  • Loading branch information
veewee authored Nov 13, 2024
2 parents 80c3f57 + 1d75648 commit 8e809c3
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 2 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ This service will be converted into metadata you, as a human, can understand.
You can apply additional service selection criteria that will be used to find the SOAP service you prefer. By default,

* The selection criteria allows any SOAP service. You can disable e.g. the HTTP-based SOAP services.
* no SOAP version is preferred. The first SOAP service the system detects, will be selected. But you can specify a specific soap version as well.

* No SOAP version is preferred. The first SOAP service the system detects, will be selected. But you can specify a specific soap version as well.
* You can specify a specific service name. If you don't, the first service will be selected.
* You can specify a specific port name. If you don't, the first port will be selected.

### WSDL2

Expand Down
20 changes: 20 additions & 0 deletions src/Locator/ServiceSelectionCriteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ final class ServiceSelectionCriteria
{
public ?SoapVersion $preferredSoapVersion;
public bool $allowHttpPorts;
public ?string $serviceName = null;
public ?string $portName = null;

public function __construct()
{
$this->preferredSoapVersion = null;
$this->allowHttpPorts = true;
$this->serviceName = null;
$this->portName = null;
}

public static function defaults(): self
Expand All @@ -36,4 +40,20 @@ public function withPreferredSoapVersion(?SoapVersion $preferredSoapVersion = nu

return $new;
}

public function withServiceName(?string $serviceName = null): self
{
$new = clone $this;
$new->serviceName = $serviceName;

return $new;
}

public function withPortName(?string $portName = null): self
{
$new = clone $this;
$new->portName = $portName;

return $new;
}
}
4 changes: 4 additions & 0 deletions src/Locator/Wsdl1SelectedServiceLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ final class Wsdl1SelectedServiceLocator
public function __invoke(Wsdl1 $wsdl, ServiceSelectionCriteria $criteria): Wsdl1SelectedService
{
foreach ($wsdl->services->items as $service) {
if ($criteria->serviceName !== null && $service->name !== $criteria->serviceName) {
continue;
}

$port = $service->ports->lookupByLookupServiceCriteria($criteria);
$binding = $port->andThen(
static fn (Port $port): Option => $wsdl->bindings->lookupByName($port->binding->localName)
Expand Down
5 changes: 5 additions & 0 deletions src/Model/Definitions/Ports.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function lookupByLookupServiceCriteria(ServiceSelectionCriteria $criteria
{
$preferredVersion = $criteria->preferredSoapVersion;
$allowHttp = $criteria->allowHttpPorts;
$portName = $criteria->portName;

foreach ($this->items as $port) {
if (!$allowHttp && $port->address->type->isHttp()) {
Expand All @@ -44,6 +45,10 @@ public function lookupByLookupServiceCriteria(ServiceSelectionCriteria $criteria
continue;
}

if ($portName !== null && $port->name !== $criteria->portName) {
continue;
}

return some($port);
}

Expand Down
126 changes: 126 additions & 0 deletions tests/Unit/Locator/Wsdl1SelectedServiceLocatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php declare(strict_types=1);

namespace Soap\WsdlReader\Test\Unit\Locator;

use Closure;
use PHPUnit\Framework\TestCase;
use Soap\Wsdl\Loader\StreamWrapperLoader;
use Soap\WsdlReader\Exception\ServiceException;
use Soap\WsdlReader\Locator\ServiceSelectionCriteria;
use Soap\WsdlReader\Locator\Wsdl1SelectedServiceLocator;
use Soap\WsdlReader\Model\Definitions\SoapVersion;
use Soap\WsdlReader\Model\Service\Wsdl1SelectedService;
use Soap\WsdlReader\Wsdl1Reader;

final class Wsdl1SelectedServiceLocatorTest extends TestCase
{
/**
* @dataProvider provideServiceLocations
*/
public function test_it_can_locate_service(
string $wsdl,
ServiceSelectionCriteria $criteria,
Closure $assert
): void {

$locator = new Wsdl1SelectedServiceLocator();
$wsdl1 = (new Wsdl1Reader(new StreamWrapperLoader()))($wsdl);

$service = $locator($wsdl1, $criteria);
$assert($service);
}

/**
* @dataProvider provideNotLocatableServices
*/
public function test_it_can_not_locate_service(
string $wsdl,
ServiceSelectionCriteria $criteria,
): void {
$this->expectException(ServiceException::class);

$locator = new Wsdl1SelectedServiceLocator();
$wsdl1 = (new Wsdl1Reader(new StreamWrapperLoader()))($wsdl);

$locator($wsdl1, $criteria);
}

public static function provideServiceLocations(): iterable
{
$weatherWs = FIXTURE_DIR . '/wsdl/weather-ws.wsdl';

yield 'first-default' => [
$weatherWs,
ServiceSelectionCriteria::defaults(),
self::assertSoapWeather11Service(...),
];

yield 'first-http' => [
$weatherWs,
ServiceSelectionCriteria::defaults()
->withServiceName('Weather')
->withPortName('WeatherHttpGet')
->withAllowHttpPorts(),
self::assertSoapHttpGetService(...),
];

yield 'first-soap12' => [
$weatherWs,
ServiceSelectionCriteria::defaults()
->withPreferredSoapVersion(SoapVersion::SOAP_12),
self::assertSoapWeather12Service(...),
];
}

public static function provideNotLocatableServices(): iterable
{
$weatherWs = FIXTURE_DIR . '/wsdl/weather-ws.wsdl';

yield 'invalid-service-name' => [
$weatherWs,
ServiceSelectionCriteria::defaults()->withServiceName('invalid'),
];

yield 'invalid-port-name' => [
$weatherWs,
ServiceSelectionCriteria::defaults()->withPortName('invalid'),
];

}

private static function assertSoapWeather11Service(Wsdl1SelectedService $service): void
{
static::assertSame('Weather', $service->service->name);
static::assertSame('WeatherSoap', $service->port->name);
static::assertSame('http://wsf.cdyne.com/WeatherWS/Weather.asmx', $service->port->address->location);
static::assertSame(true, $service->port->address->type->isSoap());
static::assertSame(SoapVersion::SOAP_11, $service->port->address->type->soapVersion());
static::assertSame('WeatherSoap', $service->binding->name);
static::assertSame('WeatherSoap', $service->portType->name);
static::assertSame('GetWeatherInformationSoapIn', $service->messages->items[0]->name);
}

private static function assertSoapWeather12Service(Wsdl1SelectedService $service): void
{
static::assertSame('Weather', $service->service->name);
static::assertSame('WeatherSoap12', $service->port->name);
static::assertSame('http://wsf.cdyne.com/WeatherWS/Weather.asmx', $service->port->address->location);
static::assertSame(true, $service->port->address->type->isSoap());
static::assertSame(SoapVersion::SOAP_12, $service->port->address->type->soapVersion());
static::assertSame('WeatherSoap12', $service->binding->name);
static::assertSame('WeatherSoap', $service->portType->name);
static::assertSame('GetWeatherInformationSoapIn', $service->messages->items[0]->name);
}

private static function assertSoapHttpGetService(Wsdl1SelectedService $service): void
{
static::assertSame('Weather', $service->service->name);
static::assertSame('WeatherHttpGet', $service->port->name);
static::assertSame('http://wsf.cdyne.com/WeatherWS/Weather.asmx', $service->port->address->location);
static::assertSame(false, $service->port->address->type->isSoap());
static::assertSame(null, $service->port->address->type->soapVersion());
static::assertSame('WeatherHttpGet', $service->binding->name);
static::assertSame('WeatherHttpGet', $service->portType->name);
static::assertSame('GetWeatherInformationSoapIn', $service->messages->items[0]->name);
}
}

0 comments on commit 8e809c3

Please sign in to comment.