Code

< 40 %
40-60 %
> 60 %
1
<?php
2
3
namespace SchulIT\IdpExchange;
4
5
use GuzzleHttp\Client as GuzzleClient;
6
use GuzzleHttp\Exception\GuzzleException;
7
use JMS\Serializer\DeserializationContext;
8
use JMS\Serializer\SerializationContext;
9
use JMS\Serializer\SerializerInterface;
10
use Psr\Log\LoggerInterface;
11
use Psr\Log\NullLogger;
12
use SchulIT\IdpExchange\Request\Builder\UpdatedUsersRequestBuilder;
13
use SchulIT\IdpExchange\Request\Builder\UserRequestBuilder;
14
use SchulIT\IdpExchange\Request\Builder\UsersRequestBuilder;
15
use SchulIT\IdpExchange\Response\UpdatedUsersResponse;
16
use SchulIT\IdpExchange\Response\UserResponse;
17
use SchulIT\IdpExchange\Response\UsersResponse;
18
19
class Client {
20
    private const TOKEN_HEADER = 'X-Token';
21
    private const UPDATED_USERS_ENDPOINT = '/exchange/updated_users';
22
    private const USERS_ENDPOINT = '/exchange/users';
23
    private const USER_ENDPOINT = '/exchange/user';
24
25
    private $endpoint;
26
    private $token;
27
    private $guzzle;
28
    private $serializer;
29
    private $logger;
30
31 12
    public function __construct(string $endpoint, string $token, GuzzleClient $guzzle, SerializerInterface $serializer, LoggerInterface $logger = null) {
32 12
        $this->endpoint = $endpoint;
33 12
        $this->token = $token;
34 12
        $this->guzzle = $guzzle;
35 12
        $this->serializer = $serializer;
36 12
        $this->logger = $logger ?? new NullLogger();
37 12
    }
38
39
    /**
40
     * @param $request
41
     * @param string $endpoint
42
     * @return mixed|\Psr\Http\Message\ResponseInterface
43
     * @throws ClientException
44
     * @throws GuzzleException
45
     */
46 12
    private function request($request, string $endpoint) {
47 12
        $context = (new SerializationContext())
48 12
            ->setSerializeNull(true);
49
50 12
        $jsonBody = $this->serializer->serialize($request, 'json', $context);
51
52 12
        $response = $this->guzzle->request('POST', $this->getEndpointFor($endpoint), [
53
            'headers' => [
54 12
                static::TOKEN_HEADER => $this->token
55
            ],
56 12
            'accept' => 'application/json',
57 12
            'body' => $jsonBody
58
        ]);
59
60 6
        if($response->getStatusCode() !== 200) {
61 3
            $this->logger->debug(sprintf('Request failed with response code %d', $response->getStatusCode()), [
62 3
                'response' => $response->getBody()->getContents()
63
            ]);
64
65 3
            throw new ClientException(sprintf('Request failed with response code %d', $response->getStatusCode()));
66
        }
67
68 3
        return $response;
69
    }
70
71
    /**
72
     * @param string $json
73
     * @param string $type
74
     * @return array|\JMS\Serializer\scalar|mixed|object
75
     */
76 3
    private function deserialize(string $json, string $type) {
77 3
        $object = $this->serializer->deserialize($json, $type, 'json');
78 3
        return $object;
79
    }
80
81 12
    private function getEndpointFor(string $endpoint): string {
82 12
        return sprintf('%s%s', $this->endpoint, $endpoint);
83
    }
84
85
    /**
86
     * @param string[] $users
87
     * @param \DateTime $since
88
     * @return UpdatedUsersResponse
89
     * @throws ClientException
90
     */
91 4
    public function getUpdatedUsers(array $users, \DateTime $since): UpdatedUsersResponse {
92 4
        $this->logger->debug('getUpdatedUsers() started');
93
94
        try {
95 4
            $request = (new UpdatedUsersRequestBuilder())
96 4
                ->addUsers($users)
97 4
                ->since($since)
98 4
                ->build();
99
100 4
            $response = $this->request($request, static::UPDATED_USERS_ENDPOINT);
101
102 1
            return $this->deserialize($response->getBody()->getContents(), UpdatedUsersResponse::class);
103 3
        } catch (GuzzleException $e) {
104 2
            $this->logger->error('Request failed with exception', [
105 2
                'exception' => $e
106
            ]);
107
108 2
            throw new ClientException($e->getMessage(), $e->getCode(), $e);
109
        } finally {
110 4
            $this->logger->debug('getUpdatedUsers() finished');
111
        }
112
    }
113
114
    /**
115
     * @param string[] $users
116
     * @return UsersResponse
117
     * @throws ClientException
118
     */
119 4
    public function getUsers(array $users): UsersResponse {
120 4
        $this->logger->debug('getUsers() started');
121
122
        try {
123 4
            $request = (new UsersRequestBuilder())
124 4
                ->addUsers($users)
125 4
                ->build();
126
127 4
            $response = $this->request($request, static::USERS_ENDPOINT);
128
129 1
            return $this->deserialize($response->getBody()->getContents(), UsersResponse::class);
130 3
        } catch (GuzzleException $e) {
131 2
            $this->logger->error('Request failed with exception', [
132 2
                'exception' => $e
133
            ]);
134
135 2
            throw new ClientException($e->getMessage(), $e->getCode(), $e);
136
        } finally {
137 4
            $this->logger->debug('getUsers() finished');
138
        }
139
    }
140
141
    /**
142
     * @param string $username
143
     * @return UserResponse
144
     * @throws ClientException
145
     */
146 4
    public function getUser(string $username): UserResponse {
147 4
        $this->logger->debug('getUser() started');
148
149
        try {
150 4
            $request = (new UserRequestBuilder())
151 4
                ->setUsername($username)
152 4
                ->build();
153
154 4
            $response = $this->request($request, static::USER_ENDPOINT);
155
156 1
            return $this->deserialize($response->getBody()->getContents(), UserResponse::class);
157 3
        } catch (GuzzleException $e) {
158 2
            $this->logger->error('Request failed with exception', [
159 2
                'exception' => $e
160
            ]);
161
162 2
            throw new ClientException($e->getMessage(), $e->getCode(), $e);
163
        } finally {
164 4
            $this->logger->debug('getUser() finished');
165
        }
166
    }
167
}