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

Add additional service selection criteria #38

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
Loading