libzypp  17.37.18
MirroredOrigin.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 #include "MirroredOrigin.h"
10 
12 #undef ZYPP_BASE_LOGGER_LOGGROUP
13 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::MirroredOrigin"
14 
15 namespace zypp {
16 
18 
19  Private( Url &&u, OriginEndpoint::SettingsMap &&m )
20  : _url(std::move(u))
21  , _settings(std::move(m))
22  {}
23  ~Private() = default;
24 
25  Private *clone () const {
26  return new Private(*this);
27  }
28 
30  std::unordered_map<std::string, std::any> _settings;
31  //OriginEndpoint::SettingsMap _settings;
32  };
33 
35  : _pimpl( new Private(Url(), {} ) )
36  {}
37 
38  OriginEndpoint::OriginEndpoint( Url url, SettingsMap settings )
39  : _pimpl( new Private(std::move(url), std::move(settings) ) )
40  {}
41 
43  : OriginEndpoint( std::move(url), SettingsMap() )
44  { }
45 
47  {
48  return _pimpl->_url;
49  }
50 
51  const Url &OriginEndpoint::url() const
52  {
53  return _pimpl->_url;
54  }
55 
56  void OriginEndpoint::setUrl(const Url &newUrl)
57  {
58  _pimpl->_url = newUrl;
59  }
60 
61  bool OriginEndpoint::hasConfig(const std::string &key) const
62  {
63  return (_pimpl->_settings.count (key) > 0);
64  }
65 
66  std::string OriginEndpoint::scheme() const
67  {
68  return _pimpl->_url.getScheme();
69  }
70 
72  {
73  return _pimpl->_url.schemeIsDownloading ();
74  }
75 
77  {
78  return _pimpl->_url.isValid();
79  }
80 
81  void OriginEndpoint::setConfig(const std::string &key, std::any value)
82  {
83  _pimpl->_settings.insert_or_assign ( key, std::move(value) );
84  }
85 
86  const std::any &OriginEndpoint::getConfig(const std::string &key) const
87  {
88  return _pimpl->_settings.at(key);
89  }
90 
91  std::any &OriginEndpoint::getConfig(const std::string &key)
92  {
93  return _pimpl->_settings.at(key);
94  }
95 
96  void OriginEndpoint::eraseConfigValue( const std::string &key )
97  {
98  auto it = _pimpl->_settings.find (key);
99  if ( it == _pimpl->_settings.end() )
100  return;
101  _pimpl->_settings.erase(it);
102  }
103 
104  const OriginEndpoint::SettingsMap &OriginEndpoint::config() const
105  {
106  return _pimpl->_settings;
107  }
108 
109 
110  OriginEndpoint::SettingsMap &OriginEndpoint::config()
111  {
112  return _pimpl->_settings;
113  }
114 
115 
116  std::ostream & operator<<( std::ostream & str, const OriginEndpoint & url )
117  {
118  return str << url.url().asString();
119  }
120 
121  bool operator<( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
122  {
123  return (lhs.url().asCompleteString() < rhs.url().asCompleteString());
124  }
125 
126  bool operator==( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
127  {
128  return (lhs.url().asCompleteString() == rhs.url().asCompleteString());
129  }
130 
131  bool operator!=( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
132  {
133  return (lhs.url().asCompleteString() != rhs.url().asCompleteString());
134  }
135 
137  Private( OriginEndpoint &&authority = {}, std::vector<OriginEndpoint> &&mirrors = {} )
138  : _authority( std::move(authority) )
139  , _mirrors( std::move(mirrors) )
140  {}
141  ~Private() = default;
142 
143  Private *clone () const {
144  return new Private(*this);
145  }
146 
148  std::vector<OriginEndpoint> _mirrors;
149  };
150 
152  : _pimpl( new Private() )
153  {}
154 
155  MirroredOrigin::MirroredOrigin(OriginEndpoint authority, std::vector<OriginEndpoint> mirrors )
156  : _pimpl( new Private( std::move(authority) ) )
157  {
158  for( auto &m : mirrors ) { addMirror ( std::move(m) ); }
159  }
160 
162  {
163  const auto &newScheme = newAuthority.scheme();
164  bool newAuthIsDl = newAuthority.url().schemeIsDownloading();
165 
166  _pimpl->_authority = std::move(newAuthority);
167 
168  if ( !_pimpl->_authority.isValid() || !_pimpl->_mirrors.size () )
169  return;
170 
171  // house keeeping, we want only compatible mirrors
172  for ( auto i = _pimpl->_mirrors.begin (); i != _pimpl->_mirrors.end(); ) {
173  if ( ( newAuthIsDl && !i->schemeIsDownloading() ) // drop mirror if its not downloading but authority is
174  && ( i->scheme () != newScheme ) // otherwise drop if scheme is not identical
175  ) {
176  MIL << "Dropping mirror " << *i << " scheme is not compatible to new authority URL ( " << i->scheme() << " vs " << newScheme << ")" << std::endl;
177  i = _pimpl->_mirrors.erase(i);
178  } else {
179  i++;
180  }
181  }
182  }
183 
185  {
186  return _pimpl->_authority;
187  }
188 
189  const std::vector<OriginEndpoint> &MirroredOrigin::mirrors() const
190  {
191  return _pimpl->_mirrors;
192  }
193 
195  {
196  return _pimpl->_authority.isValid();
197  }
198 
200  {
201  if ( _pimpl->_authority.isValid()
202  && ( _pimpl->_authority.schemeIsDownloading() && !newMirror.schemeIsDownloading () )
203  && ( _pimpl->_authority.scheme () != newMirror.scheme () )
204 
205  ) {
206  MIL << "Ignoring mirror " << newMirror << " scheme is not compatible to new authority URL ( " << newMirror.scheme() << " vs " << _pimpl->_authority.scheme() << ")" << std::endl;
207  return false;
208  }
209  _pimpl->_mirrors.push_back( std::move(newMirror) );
210  return true;
211  }
212 
213  void MirroredOrigin::setMirrors(std::vector<OriginEndpoint> mirrors)
214  {
215  clearMirrors();
216  for ( auto &m : mirrors )
217  addMirror( std::move(m) );
218  }
219 
221  {
222  _pimpl->_mirrors.clear();
223  }
224 
225  std::string MirroredOrigin::scheme() const
226  {
227  return _pimpl->_authority.url().getScheme();
228  }
229 
231  {
232  return _pimpl->_authority.schemeIsDownloading();
233  }
234 
236  {
237  // authority is always accessible, even if its a invalid URL
238  return _pimpl->_mirrors.size() + 1;
239  }
240 
241  const OriginEndpoint &MirroredOrigin::at(uint index) const
242  {
243  if ( index >= endpointCount() ) {
244  throw std::out_of_range( "OriginEndpoint index out of range." );
245  }
246  if ( index == 0 ) {
247  return _pimpl->_authority;
248  }
249 
250  return _pimpl->_mirrors.at( index - 1 );
251  }
252 
254  {
255  if ( index >= endpointCount() ) {
256  throw std::out_of_range( "OriginEndpoint index out of range." );
257  }
258  if ( index == 0 ) {
259  return _pimpl->_authority;
260  }
261 
262  return _pimpl->_mirrors.at( index - 1 );
263  }
264 
266  {
267  Private() {}
268  ~Private() = default;
269 
270  Private *clone () const {
271  return new Private(*this);
272  }
273 
274  std::optional<std::size_t> _dlIndex; //< set if there is a downloading MirroredOrigin
275  std::vector<MirroredOrigin> _mirrors;
276  };
277 
278 
280  : _pimpl( new Private() )
281  {}
282 
283  MirroredOriginSet::MirroredOriginSet( std::vector<OriginEndpoint> eps )
285  {
286  if ( eps.size() )
287  addEndpoints( std::move(eps) );
288  }
289 
292  {
293  for( auto &url: urls )
294  addEndpoint( std::move(url) );
295  }
296 
299  {
300  for( auto &url: urls )
301  addEndpoint( std::move(url) );
302  }
303 
305  {
306  return _pimpl->_mirrors.at(idx);
307  }
308 
310  {
311  return _pimpl->_mirrors.at(idx);
312  }
313 
314  std::ostream & operator<<( std::ostream & str, const MirroredOrigin & origin )
315  {
316  return dumpRange( str << "MirroredOrigin { authority: \"" << origin.authority() << "\", ",
317  origin.mirrors().begin(), origin.mirrors().end(), "mirrors: [", "\"", "\",\"", "\"", "]" )
318  << " }";
319  }
320 
322  {
323  for ( auto i = begin(); i!=end(); i++ ) {
324  auto epI = std::find_if( i->begin (), i->end(), [&](const OriginEndpoint &ep){ return ep.url () == url; } );
325  if ( epI != i->end() )
326  return i;
327  }
328  return end();
329  }
330 
332  {
333  for ( auto i = begin(); i!=end(); i++ ) {
334  auto epI = std::find_if( i->begin (), i->end(), [&](const OriginEndpoint &ep){ return ep.url () == url; } );
335  if ( epI != i->end() )
336  return i;
337  }
338  return end();
339  }
340 
342  {
343  if ( !endpoint.url().schemeIsDownloading () ) {
344  _pimpl->_mirrors.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
345  return;
346  }
347 
348  if ( _pimpl->_dlIndex ) {
349  _pimpl->_mirrors.at(*_pimpl->_dlIndex).addMirror( std::move(endpoint) );
350  return;
351  }
352 
353  // start a new origin
354  _pimpl->_mirrors.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
355  _pimpl->_dlIndex = _pimpl->_mirrors.size() - 1;
356  }
357 
358 
359  void MirroredOriginSet::addEndpoints( std::vector<OriginEndpoint> endpoints )
360  {
361  for ( auto &ep : endpoints )
362  addEndpoint ( std::move(ep) );
363  }
364 
366  {
367  return _pimpl->_mirrors.empty ();
368  }
369 
371  {
372  _pimpl->_mirrors.clear();
373  _pimpl->_dlIndex.reset();
374  }
375 
377  {
378  return _pimpl->_mirrors.begin ();
379  }
380 
381 
383  {
384  return _pimpl->_mirrors.end ();
385  }
386 
387 
389  {
390  return _pimpl->_mirrors.begin ();
391  }
392 
393 
395  {
396  return _pimpl->_mirrors.end ();
397  }
398 
400  {
401  return _pimpl->_mirrors.size ();
402  }
403 
405  {
406  return ( size() == 1 && at( 0 ).endpointCount() > 1 ) || size() > 1;
407  }
408 
409  std::ostream & operator<<( std::ostream & str, const MirroredOriginSet & origin )
410  {
411  return dumpRange( str, origin.begin(), origin.end(), "MirroredOriginSet {", " ", ", ", " ", "}" );
412  }
413 
414 }
bool operator!=(const OriginEndpoint &lhs, const OriginEndpoint &rhs)
needed for find, two OriginEndpoint&#39;s are equal when the Urls match, currently settings are not compa...
#define MIL
Definition: Logger.h:100
void setUrl(const zypp::Url &newUrl)
iterator begin()
Returns an iterator to the first MirroredOrigin in insertion order.
std::vector< MirroredOrigin >::const_iterator const_iterator
Private(Url &&u, OriginEndpoint::SettingsMap &&m)
iterator end()
Returns an iterator to the element following the last MirroredOrigin.
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:120
std::vector< OriginEndpoint > _mirrors
Private(OriginEndpoint &&authority={}, std::vector< OriginEndpoint > &&mirrors={})
String related utilities and Regular expression matching.
std::vector< MirroredOrigin > _mirrors
RWCOW_pointer< Private > _pimpl
Definition: ansi.h:854
const zypp::Url & url() const
std::string scheme() const
const MirroredOrigin & at(size_type idx) const
Accesses the MirroredOrigin at a specific index.
RWCOW_pointer< Private > _pimpl
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:515
const OriginEndpoint & at(uint index) const
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:216
void addEndpoint(OriginEndpoint endpoint)
Adds a single endpoint, routing it to the correct MirroredOrigin.
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
bool schemeIsDownloading() const
bool operator==(const OriginEndpoint &lhs, const OriginEndpoint &rhs)
needed for find, two OriginEndpoint&#39;s are equal when the Urls match, currently settings are not compa...
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:523
const std::vector< OriginEndpoint > & mirrors() const
const_iterator findByUrl(const zypp::Url &url) const
Finds the MirroredOrigin that contains a specific URL.
std::unordered_map< std::string, std::any > _settings
std::vector< MirroredOrigin >::iterator iterator
bool schemeIsDownloading() const
bool hasFallbackUrls() const
Whether this set contains more than one Url in total (authorities or mirrors).
std::string scheme() const
RWCOW_pointer< Private > _pimpl
void addEndpoints(InputIterator first, InputIterator last)
A convenience method to add multiple endpoints from a range.
zypp::Url Url
Definition: url.h:15
void setMirrors(std::vector< OriginEndpoint > mirrors)
size_type size() const
Returns the number of MirroredOrigin objects in the set.
bool addMirror(OriginEndpoint newMirror)
uint endpointCount() const
void setAuthority(OriginEndpoint newAuthority)
bool operator<(const OriginEndpoint &lhs, const OriginEndpoint &rhs)
needed for std::set
static bool schemeIsDownloading(const std::string &scheme_r)
http https ftp sftp tftp
Definition: Url.cc:493
const OriginEndpoint & authority() const
Represents a single, configurable network endpoint, combining a URL with specific access settings...
bool hasConfig(const std::string &key) const
Url manipulation class.
Definition: Url.h:92
A smart container that manages a collection of MirroredOrigin objects, automatically grouping endpoin...
std::optional< std::size_t > _dlIndex