libzypp  17.38.7
MirroredOrigin.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 #include "MirroredOrigin.h"
10 
12 #include <algorithm>
13 
14 #undef ZYPP_BASE_LOGGER_LOGGROUP
15 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::MirroredOrigin"
16 
17 namespace zypp {
18 
20 
21  Private( Url &&u, OriginEndpoint::SettingsMap &&m )
22  : _url(std::move(u))
23  , _settings(std::move(m))
24  {}
25  ~Private() = default;
26 
27  Private *clone () const {
28  return new Private(*this);
29  }
30 
32  std::unordered_map<std::string, std::any> _settings;
33  //OriginEndpoint::SettingsMap _settings;
34  };
35 
37  : _pimpl( new Private(Url(), {} ) )
38  {}
39 
40  OriginEndpoint::OriginEndpoint( Url url, SettingsMap settings )
41  : _pimpl( new Private(std::move(url), std::move(settings) ) )
42  {}
43 
45  : OriginEndpoint( std::move(url), SettingsMap() )
46  { }
47 
49  {
50  return _pimpl->_url;
51  }
52 
53  const Url &OriginEndpoint::url() const
54  {
55  return _pimpl->_url;
56  }
57 
58  void OriginEndpoint::setUrl(const Url &newUrl)
59  {
60  _pimpl->_url = newUrl;
61  }
62 
63  bool OriginEndpoint::hasConfig(const std::string &key) const
64  {
65  return (_pimpl->_settings.count (key) > 0);
66  }
67 
68  std::string OriginEndpoint::scheme() const
69  {
70  return _pimpl->_url.getScheme();
71  }
72 
74  {
75  return _pimpl->_url.schemeIsDownloading ();
76  }
77 
79  {
80  return _pimpl->_url.isValid();
81  }
82 
83  void OriginEndpoint::setConfig(const std::string &key, std::any value)
84  {
85  _pimpl->_settings.insert_or_assign ( key, std::move(value) );
86  }
87 
88  const std::any &OriginEndpoint::getConfig(const std::string &key) const
89  {
90  return _pimpl->_settings.at(key);
91  }
92 
93  std::any &OriginEndpoint::getConfig(const std::string &key)
94  {
95  return _pimpl->_settings.at(key);
96  }
97 
98  void OriginEndpoint::eraseConfigValue( const std::string &key )
99  {
100  auto it = _pimpl->_settings.find (key);
101  if ( it == _pimpl->_settings.end() )
102  return;
103  _pimpl->_settings.erase(it);
104  }
105 
106  const OriginEndpoint::SettingsMap &OriginEndpoint::config() const
107  {
108  return _pimpl->_settings;
109  }
110 
111 
112  OriginEndpoint::SettingsMap &OriginEndpoint::config()
113  {
114  return _pimpl->_settings;
115  }
116 
117 
118  std::ostream & operator<<( std::ostream & str, const OriginEndpoint & url )
119  {
120  return str << url.url().asString();
121  }
122 
123  bool operator<( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
124  {
125  return (lhs.url().asCompleteString() < rhs.url().asCompleteString());
126  }
127 
128  bool operator==( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
129  {
130  return (lhs.url().asCompleteString() == rhs.url().asCompleteString());
131  }
132 
133  bool operator!=( const OriginEndpoint &lhs, const OriginEndpoint &rhs )
134  {
135  return (lhs.url().asCompleteString() != rhs.url().asCompleteString());
136  }
137 
139  Private() = default;
140  ~Private() = default;
141 
142  Private *clone () const {
143  return new Private(*this);
144  }
145 
146  bool authoritiesAreValid() const
147  {
148  return !_authorities.empty();
149  }
150 
151  std::vector<OriginEndpoint> _authorities;
152  std::vector<OriginEndpoint> _origins;
153  };
154 
156  : _pimpl( new Private() )
157  {}
158 
159  MirroredOrigin::MirroredOrigin(OriginEndpoint authority, std::vector<OriginEndpoint> mirrors )
160  : _pimpl( new Private() )
161  {
162  if ( authority.isValid() )
163  _pimpl->_authorities.push_back( std::move(authority) );
164  else
165  WAR << "Ignoring invalid authority in constructor: " << authority << std::endl;
166 
167  for( auto &m : mirrors ) { addMirror ( std::move(m) ); }
168  }
169 
171  {
172  if ( !newAuthority.isValid() )
173  {
174  WAR << "Skipping authority " << newAuthority << ", is NOT valid" << std::endl;
175  return;
176  }
177 
178  const auto &newScheme = newAuthority.scheme();
179  bool newAuthIsDl = newAuthority.url().schemeIsDownloading();
180 
181  _pimpl->_authorities.clear();
182  _pimpl->_authorities.push_back( std::move(newAuthority) );
183 
184  if ( !_pimpl->authoritiesAreValid() || !_pimpl->_origins.size () )
185  return;
186 
187  // house keeeping, we want only compatible mirrors
188  for ( auto i = _pimpl->_origins.begin (); i != _pimpl->_origins.end(); ) {
189  if ( ( newAuthIsDl && !i->schemeIsDownloading() ) // drop mirror if its not downloading but authority is
190  && ( i->scheme () != newScheme ) // otherwise drop if scheme is not identical
191  ) {
192  MIL << "Dropping mirror " << *i << " scheme is not compatible to new authority URL ( " << i->scheme() << " vs " << newScheme << ")" << std::endl;
193  i = _pimpl->_origins.erase(i);
194  } else {
195  i++;
196  }
197  }
198  }
199 
200  const std::vector<OriginEndpoint> &MirroredOrigin::authorities() const
201  {
202  return _pimpl->_authorities;
203  }
204 
206  {
207  if (_pimpl->_authorities.empty()) {
208  static auto origin = OriginEndpoint();
209  return origin;
210  }
211  return _pimpl->_authorities[0];
212  }
213 
214  const std::vector<OriginEndpoint> &MirroredOrigin::mirrors() const
215  {
216  return _pimpl->_origins;
217  }
218 
220  {
221  return _pimpl->authoritiesAreValid();
222  }
223 
225  {
226  if (!newAuthority.isValid()) {
227  MIL << "Skipping authority " << newAuthority << ", is NOT valid" << std::endl;
228  return false;
229  }
230 
231  if ( _pimpl->authoritiesAreValid() ) {
232  const auto &authScheme = _pimpl->_authorities[0].scheme();
233  bool authIsDl = _pimpl->_authorities[0].schemeIsDownloading();
234 
235  if ( ( authIsDl && !newAuthority.schemeIsDownloading () )
236  && ( authScheme != newAuthority.scheme () )
237  ) {
238  MIL << "Ignoring authority " << newAuthority << " scheme is not compatible to current authority URL ( " << newAuthority.scheme() << " vs " << authScheme << ")" << std::endl;
239  return false;
240  }
241  }
242 
243  if (std::find(_pimpl->_authorities.begin(), _pimpl->_authorities.end(), newAuthority) != _pimpl->_authorities.end()) {
244  MIL << "Ignoring authority " << newAuthority << " already present in authorities" << std::endl;
245  return true;
246  }
247 
248  _pimpl->_authorities.push_back( std::move(newAuthority) );
249  return true;
250  }
251 
253  {
254  if ( !newMirror.isValid() ) {
255  MIL << "Ignoring mirror " << newMirror << " is not valid" << std::endl;
256  return false;
257  }
258 
259  if ( _pimpl->authoritiesAreValid() ) {
260  const auto &authScheme = _pimpl->_authorities[0].scheme();
261  bool authIsDl = _pimpl->_authorities[0].schemeIsDownloading();
262 
263  if ( ( authIsDl && !newMirror.schemeIsDownloading () )
264  && ( authScheme != newMirror.scheme () )
265  ) {
266  MIL << "Ignoring mirror " << newMirror << " scheme is not compatible to authority URL ( " << newMirror.scheme() << " vs " << authScheme << ")" << std::endl;
267  return false;
268  }
269  }
270 
271  if (std::find(_pimpl->_authorities.begin(), _pimpl->_authorities.end(), newMirror) != _pimpl->_authorities.end()) {
272  MIL << "Ignoring mirror " << newMirror << " already present in authorities" << std::endl;
273  return true;
274  }
275 
276  if (std::find(_pimpl->_origins.begin(), _pimpl->_origins.end(), newMirror) != _pimpl->_origins.end()) {
277  MIL << "Ignoring mirror " << newMirror << " already present in mirrors" << std::endl;
278  return true;
279  }
280 
281  _pimpl->_origins.push_back( std::move(newMirror) );
282  return true;
283  }
284 
285  void MirroredOrigin::setMirrors(std::vector<OriginEndpoint> mirrors)
286  {
287  clearMirrors();
288  for ( auto &m : mirrors )
289  addMirror( std::move(m) );
290  }
291 
293  {
294  _pimpl->_origins.clear();
295  }
296 
297  std::string MirroredOrigin::scheme() const
298  {
299  if ( _pimpl->_authorities.empty() )
300  return std::string();
301  return _pimpl->_authorities[0].url().getScheme();
302  }
303 
305  {
306  if ( _pimpl->_authorities.empty() )
307  return false;
308  return _pimpl->_authorities[0].schemeIsDownloading();
309  }
310 
312  {
313  return _pimpl->_authorities.size() + _pimpl->_origins.size();
314  }
315 
317  {
318  return _pimpl->_authorities.size();
319  }
320 
321  const OriginEndpoint &MirroredOrigin::at(uint index) const
322  {
323  if ( index >= endpointCount() ) {
324  throw std::out_of_range( "OriginEndpoint index out of range." );
325  }
326  if ( index < _pimpl->_authorities.size() ) {
327  return _pimpl->_authorities[index];
328  }
329 
330  return _pimpl->_origins.at( index - _pimpl->_authorities.size() );
331  }
332 
334  {
335  if ( index >= endpointCount() ) {
336  throw std::out_of_range( "OriginEndpoint index out of range." );
337  }
338  if ( index < _pimpl->_authorities.size() ) {
339  return _pimpl->_authorities[index];
340  }
341 
342  return _pimpl->_origins.at( index - _pimpl->_authorities.size() );
343  }
344 
346  {
347  Private() {}
348  ~Private() = default;
349 
350  Private *clone () const {
351  return new Private(*this);
352  }
353 
354  std::optional<std::size_t> _dlIndex; //< set if there is a downloading MirroredOrigin
355  std::vector<MirroredOrigin> _origins;
356  };
357 
358 
360  : _pimpl( new Private() )
361  {}
362 
363  MirroredOriginSet::MirroredOriginSet( std::vector<OriginEndpoint> eps )
365  {
366  if ( eps.size() )
367  addEndpoints( std::move(eps) );
368  }
369 
372  {
373  for( auto &url: urls )
374  addEndpoint( std::move(url) );
375  }
376 
379  {
380  for( auto &url: urls )
381  addEndpoint( std::move(url) );
382  }
383 
385  {
386  return _pimpl->_origins.at(idx);
387  }
388 
390  {
391  return _pimpl->_origins.at(idx);
392  }
393 
394  std::ostream & operator<<( std::ostream & str, const MirroredOrigin & origin )
395  {
396  str << "MirroredOrigin { ";
397  dumpRange( str, origin.authorities().begin(), origin.authorities().end(), "authorities: [", "\"", "\",\"", "\"", "]" );
398  str << ", ";
399  dumpRange( str, origin.mirrors().begin(), origin.mirrors().end(), "mirrors: [", "\"", "\",\"", "\"", "]" );
400  return str << " }";
401  }
402 
404  {
405  for ( auto i = begin(); i!=end(); i++ ) {
406  auto epI = std::find_if( i->begin (), i->end(), [&](const OriginEndpoint &ep){ return ep.url () == url; } );
407  if ( epI != i->end() )
408  return i;
409  }
410  return end();
411  }
412 
414  {
415  for ( auto i = begin(); i!=end(); i++ ) {
416  auto epI = std::find_if( i->begin (), i->end(), [&](const OriginEndpoint &ep){ return ep.url () == url; } );
417  if ( epI != i->end() )
418  return i;
419  }
420  return end();
421  }
422 
424  {
425  if ( !endpoint.url().schemeIsDownloading () ) {
426  _pimpl->_origins.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
427  return;
428  }
429 
430  if ( _pimpl->_dlIndex ) {
431  _pimpl->_origins.at(*_pimpl->_dlIndex).addAuthority( std::move(endpoint) );
432  return;
433  }
434 
435  // start a new origin
436  _pimpl->_origins.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
437  _pimpl->_dlIndex = _pimpl->_origins.size() - 1;
438  }
439 
441  {
442  if ( !endpoint.url().schemeIsDownloading () ) {
443  _pimpl->_origins.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
444  return;
445  }
446 
447  if ( _pimpl->_dlIndex ) {
448  _pimpl->_origins.at(*_pimpl->_dlIndex).addMirror( std::move(endpoint) );
449  return;
450  }
451 
452  // start a new origin
453  _pimpl->_origins.push_back ( MirroredOrigin(std::move(endpoint), {} ) );
454  _pimpl->_dlIndex = _pimpl->_origins.size() - 1;
455  }
456 
457 
458  void MirroredOriginSet::addEndpoints( std::vector<OriginEndpoint> endpoints )
459  {
460  for ( auto &ep : endpoints )
461  addEndpoint ( std::move(ep) );
462  }
463 
465  {
466  return _pimpl->_origins.empty ();
467  }
468 
470  {
471  _pimpl->_origins.clear();
472  _pimpl->_dlIndex.reset();
473  }
474 
476  {
477  return _pimpl->_origins.begin ();
478  }
479 
480 
482  {
483  return _pimpl->_origins.end ();
484  }
485 
486 
488  {
489  return _pimpl->_origins.begin ();
490  }
491 
492 
494  {
495  return _pimpl->_origins.end ();
496  }
497 
499  {
500  return _pimpl->_origins.size ();
501  }
502 
504  {
505  return ( size() == 1 && at( 0 ).endpointCount() > 1 ) || size() > 1;
506  }
507 
508  std::ostream & operator<<( std::ostream & str, const MirroredOriginSet & origin )
509  {
510  return dumpRange( str, origin.begin(), origin.end(), "MirroredOriginSet {", " ", ", ", " ", "}" );
511  }
512 
513 }
#define MIL
Definition: Logger.h:103
void setUrl(const zypp::Url &newUrl)
iterator begin()
Returns an iterator to the first MirroredOrigin in insertion order.
bool operator==(const Capability &lhs, const Capability &rhs)
relates: Capability
Definition: Capability.h:309
bool addAuthority(OriginEndpoint newAuthority)
std::vector< MirroredOrigin >::const_iterator const_iterator
void addAuthorityEndpoint(OriginEndpoint endpoint)
Adds a single endpoint as an authority, routing it to the correct MirroredOrigin. ...
Private(Url &&u, OriginEndpoint::SettingsMap &&m)
iterator end()
Returns an iterator to the element following the last MirroredOrigin.
std::vector< MirroredOrigin > _origins
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:409
String related utilities and Regular expression matching.
RWCOW_pointer< Private > _pimpl
Definition: ansi.h:854
const zypp::Url & url() const
std::string scheme() const
uint authorityCount() const
const MirroredOrigin & at(size_type idx) const
Accesses the MirroredOrigin at a specific index.
std::vector< OriginEndpoint > _origins
RWCOW_pointer< Private > _pimpl
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:524
const OriginEndpoint & at(uint index) const
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
#define WAR
Definition: Logger.h:104
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:532
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
bool operator!=(const Capability &lhs, const Capability &rhs)
relates: Capability
Definition: Capability.h:313
const std::vector< OriginEndpoint > & authorities() const
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.
void setMirrors(std::vector< OriginEndpoint > mirrors)
size_type size() const
Returns the number of MirroredOrigin objects in the set.
bool addMirror(OriginEndpoint newMirror)
bool operator<(const Capability &lhs, const Capability &rhs)
relates: Capability Arbitrary order.
Definition: Capability.h:317
uint endpointCount() const
void setAuthority(OriginEndpoint newAuthority)
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition: Capabilities.cc:65
static bool schemeIsDownloading(const std::string &scheme_r)
http https ftp sftp tftp
Definition: Url.cc:493
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
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::vector< OriginEndpoint > _authorities
std::optional< std::size_t > _dlIndex