This repository was archived by the owner on Jun 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPooledServerConnectionFactory.cs
More file actions
107 lines (83 loc) · 3.68 KB
/
PooledServerConnectionFactory.cs
File metadata and controls
107 lines (83 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Net;
using LinqToLdap;
namespace ServerPoolConnectionFactory
{
public class PooledServerConnectionFactory : ILdapConnectionFactory
{
private readonly ConcurrentDictionary<string, ServerPoolMemberConnectionFactory> _servers;
public PooledServerConnectionFactory()
{
_servers = new ConcurrentDictionary<string, ServerPoolMemberConnectionFactory>(StringComparer.OrdinalIgnoreCase);
}
public void AddServer(LdapDirectoryIdentifier identifier, int maxConnections, int protocolVersion = 3, bool ssl = false, double? timeout = null, NetworkCredential credentials = null, AuthType? authType = null)
{
var serverName = identifier.Servers[0];
var factory = new LdapConnectionFactory(serverName);
if (credentials != null)
factory.AuthenticateAs(credentials);
if (authType.HasValue)
factory.AuthenticateBy(authType.Value);
if (timeout.HasValue)
factory.ConnectionTimeoutIn(timeout.Value);
factory.ProtocolVersion(protocolVersion);
if (identifier.FullyQualifiedDnsHostName)
factory.ServerNameIsFullyQualified();
if (identifier.Connectionless)
factory.UseUdp();
if (ssl) factory.UseSsl();
factory.UsePort(identifier.PortNumber);
_servers[serverName] = new ServerPoolMemberConnectionFactory(serverName, factory, maxConnections);
}
public void RemoveServer(string serverName)
{
ServerPoolMemberConnectionFactory factory;
if (!_servers.TryRemove(serverName, out factory))
{
throw new InvalidOperationException(serverName + " not found.");
}
}
public LdapConnection GetConnection()
{
var factory = _servers.FirstOrDefault(c => c.Value.CanConnect);
if (Equals(factory, default(KeyValuePair<string, ServerPoolMemberConnectionFactory>)))
throw new InvalidOperationException("No connections available");
return factory.Value.GetConnection();
}
public void ReleaseConnection(LdapConnection connection)
{
var server = ((LdapDirectoryIdentifier)connection.Directory).Servers[0];
_servers[server].ReleaseConnection(connection);
}
private class ServerPoolMemberConnectionFactory : ILdapConnectionFactory
{
private ILdapConnectionFactory _factory;
private int _maxConnections;
private int _connectionCount;
private string _serverName;
public ServerPoolMemberConnectionFactory(string serverName, ILdapConnectionFactory factory, int maxConnections)
{
_serverName = serverName;
_factory = factory;
_maxConnections = maxConnections;
}
public bool CanConnect { get { return _maxConnections > _connectionCount; } }
public LdapConnection GetConnection()
{
if (!CanConnect) throw new InvalidOperationException("Too many connections for " + _serverName);
var connection = _factory.GetConnection();
_connectionCount++;
return connection;
}
public void ReleaseConnection(LdapConnection connection)
{
_factory.ReleaseConnection(connection);
_connectionCount--;
}
}
}
}