1<?php
2
3/**
4 * This file is part of the FreeDSx LDAP package.
5 *
6 * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace FreeDSx\Ldap\Protocol\Queue;
13
14use FreeDSx\Asn1\Encoder\EncoderInterface;
15use FreeDSx\Asn1\Exception\EncoderException;
16use FreeDSx\Asn1\Exception\PartialPduException;
17use FreeDSx\Ldap\Exception\ProtocolException;
18use FreeDSx\Ldap\Exception\RuntimeException;
19use FreeDSx\Ldap\Exception\UnsolicitedNotificationException;
20use FreeDSx\Ldap\Protocol\LdapMessage;
21use FreeDSx\Ldap\Protocol\LdapMessageRequest;
22use FreeDSx\Ldap\Protocol\LdapMessageResponse;
23use FreeDSx\Ldap\Protocol\LdapQueue;
24use FreeDSx\Socket\Exception\ConnectionException;
25use FreeDSx\Socket\Queue\Message;
26use FreeDSx\Socket\SocketPool;
27
28/**
29 * The LDAP Queue class for sending and receiving messages for clients.
30 *
31 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
32 */
33class ClientQueue extends LdapQueue
34{
35    /**
36     * @var bool
37     */
38    protected $shouldReconnect = false;
39
40    /**
41     * @var SocketPool
42     */
43    protected $socketPool;
44
45    /**
46     * @throws ConnectionException
47     */
48    public function __construct(SocketPool $socketPool, EncoderInterface $encoder = null)
49    {
50        $this->socketPool = $socketPool;
51        parent::__construct($socketPool->connect(), $encoder);
52    }
53
54    /**
55     * @throws ProtocolException
56     * @throws UnsolicitedNotificationException
57     * @throws ConnectionException
58     */
59    public function getMessage(?int $id = null): LdapMessageResponse
60    {
61        $this->initSocket();
62
63        $message = $this->getAndValidateMessage($id);
64        if (!$message instanceof LdapMessageResponse) {
65            throw new ProtocolException(sprintf(
66                'Expected an instance of LdapMessageResponse but got: %s',
67                get_class($message)
68            ));
69        }
70
71        return $message;
72    }
73
74    /**
75     * @param int|null $id
76     * @return \Generator
77     * @throws ConnectionException
78     */
79    public function getMessages(?int $id = null)
80    {
81        $this->initSocket();
82
83        return parent::getMessages($id);
84    }
85
86    /**
87     * @param LdapMessageRequest ...$messages
88     * @return $this
89     * @throws ConnectionException
90     * @throws EncoderException
91     */
92    public function sendMessage(LdapMessageRequest ...$messages): self
93    {
94        $this->initSocket();
95        $this->sendLdapMessage(...$messages);
96
97        return $this;
98    }
99
100    /**
101     * {@inheritDoc}
102     */
103    public function close(): void
104    {
105        parent::close();
106        $this->shouldReconnect = true;
107    }
108
109    /**
110     * @throws ConnectionException
111     */
112    protected function initSocket(): void
113    {
114        if ($this->shouldReconnect) {
115            $this->socket = $this->socketPool->connect();
116            $this->shouldReconnect = false;
117        }
118    }
119
120    /**
121     * @param Message $message
122     * @param int|null $id
123     * @return LdapMessage
124     * @throws ProtocolException
125     * @throws EncoderException
126     * @throws PartialPduException
127     * @throws RuntimeException
128     */
129    protected function constructMessage(Message $message, ?int $id = null)
130    {
131        return LdapMessageResponse::fromAsn1($message->getMessage());
132    }
133}
134