1 /* $Id: ncbi_dbsvcmapper.cpp 626334 2021-02-25 18:42:15Z ivanov $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Aaron Ucko
27 *
28 * File Description:
29 * Database service name to server mapping policy.
30 *
31 * ===========================================================================
32 */
33
34 #include <ncbi_pch.hpp>
35
36 #include <corelib/impl/ncbi_dbsvcmapper.hpp>
37 #include <corelib/ncbierror.hpp>
38
39 BEGIN_NCBI_SCOPE
40
41
CEndpointKey(const CTempString & name,NStr::TConvErrFlags flags)42 CEndpointKey::CEndpointKey(const CTempString& name, NStr::TConvErrFlags flags)
43 {
44 CTempString address = name;
45 SIZE_TYPE pos = name.find_first_not_of("0123456789.:");
46 if (pos != NPOS) {
47 string msg = ("Unsupported endpoint key character "
48 + NStr::CEncode(CTempString(name.substr(pos, 1))));
49 if ((flags & NStr::fConvErr_NoThrow) == 0) {
50 NCBI_THROW2(CStringException, eFormat, msg, pos);
51 } else {
52 if ((flags & NStr::fConvErr_NoErrMessage) != 0) {
53 CNcbiError::Set(CNcbiError::eInvalidArgument);
54 } else {
55 CNcbiError::Set(CNcbiError::eInvalidArgument,
56 FORMAT(msg << " at position " << pos));
57 }
58 m_Value = 0;
59 return;
60 }
61 }
62 Uint2 port = 0;
63 pos = address.find(':');
64 if (pos != NPOS) {
65 if ( !NStr::StringToNumeric(address.substr(pos + 1), &port, flags)) {
66 m_Value = 0;
67 return;
68 }
69 address = address.substr(0, pos);
70 }
71 union { // to help produce network byte order
72 Uint4 i;
73 Uint1 c[4];
74 } host = { 0, };
75 if (count(address.begin(), address.end(), '.') != 3) {
76 string msg = "Wrong number of components in IP address " + address;
77 if ((flags & NStr::fConvErr_NoThrow) == 0) {
78 NCBI_THROW2(CStringException, eFormat, msg, address.size());
79 } else {
80 if ((flags & NStr::fConvErr_NoErrMessage) != 0) {
81 CNcbiError::Set(CNcbiError::eInvalidArgument);
82 } else {
83 CNcbiError::Set(CNcbiError::eInvalidArgument, msg);
84 }
85 m_Value = 0;
86 return;
87 }
88 return;
89 }
90 for (int i = 0; i < 4; ++i) {
91 CTempString component;
92 switch (i) {
93 case 0:
94 pos = address.find('.');
95 component = address.substr(0, pos);
96 break;
97 case 1: case 2:
98 {
99 SIZE_TYPE pos2 = address.find('.', pos + 1);
100 component = address.substr(pos + 1, pos2 - pos - 1);
101 pos = pos2;
102 break;
103 }
104 case 3:
105 component = address.substr(pos + 1);
106 break;
107 default:
108 _TROUBLE;
109 }
110 if ( !NStr::StringToNumeric(component, &host.c[i], flags)) {
111 m_Value = 0;
112 return;
113 }
114
115 }
116 m_Value = (TValue(host.i) << 16) | port;
117 }
118
119
operator <<(ostream & os,const CEndpointKey & key)120 ostream& operator<<(ostream& os, const CEndpointKey& key)
121 {
122 auto host = key.GetHost();
123 const unsigned char* b = (const unsigned char*) &host;
124 os << Uint4(b[0]) << '.' << Uint4(b[1]) << '.' << Uint4(b[2]) << '.'
125 << Uint4(b[3]);
126 auto port = key.GetPort();
127 if (port != 0) {
128 os << ':' << port;
129 }
130 return os;
131 }
132
133
GetServerOptions(const string & name,TOptions * options)134 void IDBServiceMapper::GetServerOptions(const string& name, TOptions* options)
135 {
136 list<string> servers;
137 GetServersList(name, &servers);
138 options->clear();
139 CFastMutexGuard mg(m_Mtx);
140 const auto& exclusions = m_ExcludeMap[name];
141 for (const string& it : servers) {
142 options->emplace_back(new CDBServerOption(it, 0, 0, 1.0));
143 auto lb = exclusions.lower_bound(options->back());
144 if (lb != exclusions.end() && (*lb)->GetName() == name) {
145 options->back()->m_State |= CDBServerOption::fState_Excluded;
146 }
147 }
148 }
149
150
151 END_NCBI_SCOPE
152