diff --git a/README.md b/README.md index b0b17cc..abb4569 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/Locator/ServiceSelectionCriteria.php b/src/Locator/ServiceSelectionCriteria.php index 28b01ee..e8d7d11 100644 --- a/src/Locator/ServiceSelectionCriteria.php +++ b/src/Locator/ServiceSelectionCriteria.php @@ -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 @@ -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; + } } diff --git a/src/Locator/Wsdl1SelectedServiceLocator.php b/src/Locator/Wsdl1SelectedServiceLocator.php index 5cfafe2..41fb1e1 100644 --- a/src/Locator/Wsdl1SelectedServiceLocator.php +++ b/src/Locator/Wsdl1SelectedServiceLocator.php @@ -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) diff --git a/src/Model/Definitions/Ports.php b/src/Model/Definitions/Ports.php index ff2dc9e..ed39060 100644 --- a/src/Model/Definitions/Ports.php +++ b/src/Model/Definitions/Ports.php @@ -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()) { @@ -44,6 +45,10 @@ public function lookupByLookupServiceCriteria(ServiceSelectionCriteria $criteria continue; } + if ($portName !== null && $port->name !== $criteria->portName) { + continue; + } + return some($port); } diff --git a/tests/Unit/Locator/Wsdl1SelectedServiceLocatorTest.php b/tests/Unit/Locator/Wsdl1SelectedServiceLocatorTest.php new file mode 100644 index 0000000..4625896 --- /dev/null +++ b/tests/Unit/Locator/Wsdl1SelectedServiceLocatorTest.php @@ -0,0 +1,126 @@ +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); + } +}