NovaApiSoapAction::appendMethodNamespaces()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 27
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 32
ccs 28
cts 28
cp 1
crap 1
rs 9.488
1
<?php
2
3
namespace OrcaServices\NovaApi\Soap;
4
5
use Cake\Chronos\Chronos;
6
use DOMDocument;
7
use DOMElement;
8
use OrcaServices\NovaApi\Client\NovaHttpClient;
9
use OrcaServices\NovaApi\Configuration\NovaApiConfiguration;
10
use OrcaServices\NovaApi\Factory\NovaHttpClientFactory;
11
use OrcaServices\NovaApi\Parameter\NovaIdentifierParameter;
12
use UnexpectedValueException;
13
14
/**
15
 * Class.
16
 */
17
final class NovaApiSoapAction
18
{
19
    /**
20
     * @var NovaHttpClientFactory HTTP client factory
21
     */
22
    private $httpClientFactory;
23
24
    /**
25
     * @var NovaHttpClient|null HTTP client
26
     */
27
    private $httpClient;
28
29
    /**
30
     * @var int Max lifetime of the token. Refresh after this time.
31
     */
32
    private $httpClientMaxLifetime = 300;
33
34
    /**
35
     * @var Chronos|null Max lifetime of the token. Refresh after this time.
36
     */
37
    private $httpClientLoginAt;
38
39
    /**
40
     * @var NovaApiConfiguration
41
     */
42
    private $configuration;
43
44
    /**
45
     * Constructor.
46
     *
47
     * @param NovaHttpClientFactory $httpClientFactory The httpClient factory
48
     * @param NovaApiConfiguration $configuration The novaVersion
49
     */
50 13
    public function __construct(NovaHttpClientFactory $httpClientFactory, NovaApiConfiguration $configuration)
51
    {
52 13
        $this->httpClientFactory = $httpClientFactory;
53 13
        $this->configuration = $configuration;
54 13
    }
55
56
    /**
57
     * Build the request URI with the given request options.
58
     *
59
     * NOVA System: VertriebsService = /novaan/*
60
     *
61
     * @return string the request URI with the nova version
62
     */
63 8
    public function getNovaSalesServiceUrl(): string
64
    {
65 8
        return str_replace(
66 8
            '{novaVersion}',
67 8
            $this->configuration->getNovaApiVersion(),
68 8
            '/novaan/vertrieb/public/{novaVersion}/VertriebsService'
69
        );
70
    }
71
72
    /**
73
     * Build the request URI with the given request options.
74
     *
75
     * NOVA System: SwisspassService = /novaan/*
76
     *
77
     * https://confluence-ext.sbb.ch/display/NOVAUG/NOVA+Umgebungsdetails
78
     *
79
     * @return string the request URI with the nova version
80
     */
81 2
    public function getNovaSwisspassServiceUrl(): string
82
    {
83 2
        return str_replace(
84 2
            '{novaVersion}',
85 2
            $this->configuration->getNovaApiVersion(),
86 2
            '/novasp/swisspass/public/{novaVersion}/SwissPassService'
87
        );
88
    }
89
90
    /**
91
     * Build the request URI with the given request options.
92
     *
93
     * NOVA System: GeschaeftspartnerService = /novagp/*
94
     *
95
     * @return string the request URI with the nova version
96
     *
97
     * @example https://nova-test-ws.sbb.ch/novagp/geschaeftspartner/public/v13/GeschaeftspartnerService
98
     */
99 3
    public function getNovaBusinessPartnerServiceUrl(): string
100
    {
101 3
        return str_replace(
102 3
            '{novaVersion}',
103 3
            $this->configuration->getNovaApiVersion(),
104 3
            '/novagp/geschaeftspartner/public/{novaVersion}/GeschaeftspartnerService'
105
        );
106
    }
107
108
    /**
109
     * Build the request URI with the given request options.
110
     *
111
     * @param string $resourceUri The resource URI with {novaVersion} placeholder
112
     *
113
     * @return string the request URI with the nova version
114
     */
115 13
    public function getNovaVersionUrl($resourceUri): string
116
    {
117 13
        return str_replace(
118 13
            '{novaVersion}',
119 13
            $this->configuration->getNovaApiVersion(),
120 13
            $resourceUri
121
        );
122
    }
123
124
    /**
125
     * Return service namespace url.
126
     *
127
     * @param string $uriPath The uri path
128
     *
129
     * @return string The full namespace url
130
     */
131 13
    public function getServiceNamespace(string $uriPath): string
132
    {
133
        // NOVA namespace base url
134 13
        $serviceBaseUrl = $this->getNovaVersionUrl('http://nova.voev.ch/services/{novaVersion}');
135
136 13
        return $serviceBaseUrl . '/' . $uriPath;
137
    }
138
139
    /**
140
     * Get SOAP Webservice schema action (for the HTTP request body).
141
     *
142
     * @param string $novaSystem The nova system (vertrieb, geschaeftspartner, ...)
143
     * @param string $soapMethod Soap method name
144
     *
145
     * @return string The action name
146
     */
147 13
    public function getSoapAction(string $novaSystem, string $soapMethod): string
148
    {
149 13
        $namespace = sprintf('http://nova.voev.ch/services/{novaVersion}/%s/%s', $novaSystem, $soapMethod);
150
151 13
        return $this->getNovaVersionUrl($namespace);
152
    }
153
154
    /**
155
     * Add TU specific parameters to the DOM.
156
     *
157
     * @param DOMDocument $dom The dom
158
     * @param DOMElement $targetElement The target dom element
159
     * @param NovaIdentifierParameter $parameter The parameter
160
     * @param string $namespace The namespace
161
     *
162
     * @return void
163
     */
164 13
    public function appendDomClientIdentifier(
165
        DOMDocument $dom,
166
        DOMElement $targetElement,
167
        NovaIdentifierParameter $parameter,
168
        string $namespace = ''
169
    ) {
170 13
        $clientIdentifier = $dom->createElement($namespace . 'clientIdentifier');
171 13
        $targetElement->appendChild($clientIdentifier);
172
173 13
        $clientIdentifier->setAttribute('base:leistungsVermittler', $parameter->serviceAgent);
174 13
        $clientIdentifier->setAttribute('base:kanalCode', $parameter->channelCode);
175 13
        $clientIdentifier->setAttribute('base:verkaufsStelle', $parameter->pointOfSale);
176 13
        $clientIdentifier->setAttribute('base:vertriebsPunkt', $parameter->distributionPoint);
177 13
        $clientIdentifier->setAttribute('base:verkaufsGeraeteId', $parameter->saleDeviceId);
178 13
    }
179
180
    /**
181
     * Add correlation context to DOM.
182
     *
183
     * @param DOMDocument $dom The dom
184
     * @param DOMElement $targetElement The target dom element
185
     * @param NovaIdentifierParameter $parameter The parameter
186
     * @param string $namespace The namespace
187
     *
188
     * @return void
189
     */
190 13
    public function appendDomCorrelationContext(
191
        DOMDocument $dom,
192
        DOMElement $targetElement,
193
        NovaIdentifierParameter $parameter,
194
        string $namespace = ''
195
    ) {
196 13
        $correlationContext = $dom->createElement($namespace . 'correlationKontext');
197 13
        $targetElement->appendChild($correlationContext);
198
199 13
        $element = $dom->createElement('base:correlationId');
200 13
        $element->appendChild($dom->createTextNode($parameter->correlationId));
201 13
        $correlationContext->appendChild($element);
202 13
    }
203
204
    /**
205
     * Append default SOAP method namespaces.
206
     *
207
     * @param DOMElement $method The method node
208
     *
209
     * @return void
210
     */
211 13
    public function appendMethodNamespaces(DOMElement $method)
212
    {
213 13
        $method->setAttribute('xmlns:ns20', 'http://nova.voev.ch/services/internal/leistungnotification');
214 13
        $method->setAttribute('xmlns:ns19', $this->getServiceNamespace('inkasso'));
215 13
        $method->setAttribute('xmlns:ns18', $this->getServiceNamespace('vertrieb'));
216 13
        $method->setAttribute('xmlns:nova-leistungnotiz', $this->getServiceNamespace('leistungnotiz'));
217 13
        $method->setAttribute('xmlns:ns16', $this->getServiceNamespace('vertrag'));
218 13
        $method->setAttribute('xmlns:vertriebsbase', $this->getServiceNamespace('vertriebsbase'));
219 13
        $method->setAttribute('xmlns:ns14', 'http://nova.voev.ch/services/internal');
220 13
        $method->setAttribute('xmlns:vs', $this->getServiceNamespace('vertrieb/vertriebsstammdaten'));
221 13
        $method->setAttribute('xmlns:nova-protokoll', $this->getServiceNamespace('vertrieb/protokoll'));
222 13
        $method->setAttribute(
223 13
            'xmlns:nova-erneuerungsinfo',
224 13
            $this->getServiceNamespace('vertrieb/erneuerungsinfo')
225
        );
226 13
        $method->setAttribute(
227 13
            'xmlns:offlinemanagement',
228 13
            $this->getServiceNamespace('vertrieb/offlinemanagement')
229
        );
230 13
        $method->setAttribute(
231 13
            'xmlns:nova-monitoring',
232 13
            $this->getServiceNamespace('internal/monitoring')
233
        );
234 13
        $method->setAttribute('xmlns:nova-preisauskunft', $this->getServiceNamespace('preisauskunft'));
235 13
        $method->setAttribute('xmlns:base', $this->getServiceNamespace('base'));
236 13
        $method->setAttribute('xmlns:ns6', $this->getServiceNamespace('fachlichervertrag'));
237 13
        $method->setAttribute('xmlns:novasp-swisspass', $this->getServiceNamespace('vertragskonto'));
238 13
        $method->setAttribute('xmlns:nova-vertragskonto', $this->getServiceNamespace('swisspass'));
239 13
        $method->setAttribute('xmlns:novasp-swisspass', $this->getServiceNamespace('swisspass'));
240 13
        $method->setAttribute('xmlns:novagp', $this->getServiceNamespace('geschaeftspartner'));
241 13
        $method->setAttribute('xmlns', $this->getServiceNamespace('vertrieb'));
242 13
        $method->setAttribute('xmlns:novavt-vertrag', $this->getServiceNamespace('vertragbase'));
243 13
    }
244
245
    /**
246
     * Invoke SOAP request.
247
     *
248
     * @param string $url The endpoint url
249
     * @param string $soapAction The SOAP action method
250
     * @param string $body The xml payload
251
     *
252
     * @throws UnexpectedValueException
253
     *
254
     * @return string The SOAP response body
255
     */
256 13
    public function invokeSoapRequest(string $url, string $soapAction, string $body): string
257
    {
258 13
        $this->loginClient();
259
260 13
        if (!$this->httpClient) {
261
            throw new UnexpectedValueException('The http client is not defined');
262
        }
263
264 13
        $response = $this->httpClient->post(
265 13
            $url,
266
            [
267 13
                'body' => $body,
268
                'headers' => [
269 13
                    'SOAPAction' => $soapAction,
270
                ],
271
            ]
272
        );
273
274 13
        return (string)$response->getBody();
275
    }
276
277
    /**
278
     * Login the http client. Creates a new login after maxLifetime seconds.
279
     *
280
     * @return void
281
     */
282 13
    private function loginClient()
283
    {
284 13
        $now = Chronos::now();
285
286 13
        $loginTimestamp = $this->httpClientLoginAt ? $this->httpClientLoginAt->getTimestamp() : 0;
287
288 13
        if ($this->httpClient === null ||
289 13
            $now->getTimestamp() - $loginTimestamp >= $this->httpClientMaxLifetime
290
        ) {
291 13
            $this->httpClientLoginAt = $now;
292 13
            $this->httpClient = $this->httpClientFactory->createLoggedInHttpClient();
293
        }
294 13
    }
295
}
296