libzypp  17.31.31
providemessage.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
11 
12 #include <zypp-core/Url.h>
13 #include <string_view>
14 #include <string>
15 
16 namespace zyppng {
17 
18  static ProvideMessage::FieldVal fieldValFromProto ( const zypp::proto::DataField &field )
19  {
21  switch ( field.field_val_case () ) {
22  case zypp::proto::DataField::FieldValCase::kBoolVal:
23  v = field.bool_val();
24  break;
25  case zypp::proto::DataField::FieldValCase::kDoubleVal:
26  v = field.double_val();
27  break;
28  case zypp::proto::DataField::FieldValCase::kIntVal:
29  v = field.int_val();
30  break;
31  case zypp::proto::DataField::FieldValCase::kLongVal:
32  v = field.long_val();
33  break;
34  case zypp::proto::DataField::FieldValCase::kStrVal:
35  v = field.str_val();
36  break;
37  case zypp::proto::DataField::FieldValCase::FIELD_VAL_NOT_SET:
38  ZYPP_THROW( std::logic_error("Unexpected DataField type"));
39  break;
40  }
41  return v;
42  }
43 
44  static void fieldValToProto ( const ProvideMessage::FieldVal &val, zypp::proto::DataField &field )
45  {
46  if ( val.isString() )
47  field.set_str_val( val.asString () );
48  else if ( val.isInt() )
49  field.set_int_val( val.asInt() );
50  else if ( val.isInt64() )
51  field.set_long_val( val.asInt64() );
52  else if ( val.isDouble() )
53  field.set_double_val( val.asDouble() );
54  else if ( val.isBool() )
55  field.set_bool_val( val.asBool() );
56  else
57  ZYPP_THROW( std::logic_error("Unexpected FieldVal type"));
58  }
59 
60  static expected<void> validateMessage ( const ProvideMessage &msg )
61  {
62  const auto c = msg.code();
63  const auto validCode = ( c >= ProvideMessage::Code::FirstInformalCode && c <= ProvideMessage::Code::LastInformalCode )
64  || ( c >= ProvideMessage::Code::FirstSuccessCode && c <= ProvideMessage::Code::LastSuccessCode )
65  || ( c >= ProvideMessage::Code::FirstRedirCode && c <= ProvideMessage::Code::LastRedirCode )
66  || ( c >= ProvideMessage::Code::FirstClientErrCode && c <= ProvideMessage::Code::LastClientErrCode )
67  || ( c >= ProvideMessage::Code::FirstSrvErrCode && c <= ProvideMessage::Code::LastSrvErrCode )
68  || ( c >= ProvideMessage::Code::FirstControllerCode && c <= ProvideMessage::Code::LastControllerCode)
69  || ( c >= ProvideMessage::Code::FirstWorkerCode && c <= ProvideMessage::Code::LastWorkerCode );
70  if ( !validCode ) {
71  return zyppng::expected<void>::error( ZYPP_EXCPT_PTR ( InvalidMessageReceivedException("Invalid code in ProvideMessage")) );
72  }
73 
74  #define DEF_REQ_FIELD( fname ) bool has_##fname = false
75 
76  #define REQ_FIELD_CHECK( msgtype, fname, ftype ) \
77  if ( name == #fname ) { \
78  if ( !std::holds_alternative<ftype>(val.asVariant()) ) { \
79  error = ZYPP_EXCPT_PTR( InvalidMessageReceivedException( zypp::str::Str() << "Parse error " << #msgtype << ", Field " << #fname << " has invalid type" ) ); \
80  return false; \
81  } \
82  has_##fname = true; \
83  }
84 
85  #define OR_REQ_FIELD_CHECK( msgtype, fname, ftype ) else REQ_FIELD_CHECK( msgtype, fname, ftype )
86 
87  #define OPT_FIELD_CHECK( msgtype, fname, ftype ) \
88  if ( name == #fname ) { \
89  if ( !std::holds_alternative<ftype>(val.asVariant() ) ) { \
90  error = ZYPP_EXCPT_PTR( InvalidMessageReceivedException( zypp::str::Str() << "Parse error " << #msgtype << ", Field " << #fname << " has invalid type" ) ); \
91  return false; \
92  } \
93  }
94 
95  #define OR_OPT_FIELD_CHECK( msgtype, fname, ftype ) else OPT_FIELD_CHECK( msgtype, fname, ftype )
96 
97  #define FAIL_IF_NOT_SEEN_REQ_FIELD( msgtype, fname ) \
98  if ( !has_##fname ) \
99  return expected<void>::error( ZYPP_EXCPT_PTR( InvalidMessageReceivedException( zypp::str::Str() << #msgtype <<" message does not contain required " << #fname << " field" ) ) )
100 
101  #define FAIL_IF_ERROR( ) \
102  if ( error ) return expected<void>::error( error )
103 
104  const auto &validateErrorMsg = []( const auto &msg ){
105  std::exception_ptr error;
106  DEF_REQ_FIELD(reason);
107  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
108  REQ_FIELD_CHECK ( Error, reason, std::string )
109  OR_OPT_FIELD_CHECK ( Error, history, std::string )
110  OR_OPT_FIELD_CHECK ( Error, transient, bool )
111  return true;
112  });
114  FAIL_IF_ERROR();
115  return expected<void>::success();
116  };
117 
118  switch ( c )
119  {
120  case ProvideMessage::Code::ProvideStarted: {
121  std::exception_ptr error;
122  DEF_REQ_FIELD(url);
123  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
124  REQ_FIELD_CHECK ( ProvideStarted, url, std::string )
125  OR_OPT_FIELD_CHECK ( ProvideStarted, local_filename, std::string )
126  OR_OPT_FIELD_CHECK ( ProvideStarted, staging_filename, std::string )
127  return true;
128  });
129  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideStarted, url );
130  FAIL_IF_ERROR();
131  break;
132  }
133  case ProvideMessage::Code::ProvideFinished: {
134  std::exception_ptr error;
135  DEF_REQ_FIELD(cacheHit);
136  DEF_REQ_FIELD(local_filename);
137  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
138  REQ_FIELD_CHECK ( ProvideFinished, cacheHit, bool )
139  OR_REQ_FIELD_CHECK ( ProvideFinished, local_filename, std::string )
140  return true;
141  });
142  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideFinished, cacheHit );
143  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideFinished, local_filename );
144  FAIL_IF_ERROR();
145  break;
146  }
147  case ProvideMessage::Code::AttachFinished: {
148  // no fields
149  break;
150  }
151  case ProvideMessage::Code::DetachFinished: {
152  // no fields
153  break;
154  }
155  case ProvideMessage::Code::AuthInfo: {
156  std::exception_ptr error;
157  DEF_REQ_FIELD(username);
158  DEF_REQ_FIELD(password);
159  DEF_REQ_FIELD(auth_timestamp);
160  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
161  REQ_FIELD_CHECK ( AuthInfo, username, std::string )
162  OR_REQ_FIELD_CHECK ( AuthInfo, password, std::string )
163  OR_REQ_FIELD_CHECK ( AuthInfo, auth_timestamp, int64_t )
164  OR_OPT_FIELD_CHECK ( AuthInfo, authType, std::string )
165  return true;
166  });
167  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideStarted, username );
168  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideStarted, password );
169  FAIL_IF_NOT_SEEN_REQ_FIELD( ProvideStarted, auth_timestamp );
170  FAIL_IF_ERROR();
171  break;
172  }
173  case ProvideMessage::Code::MediaChanged:
174  /* No Fields */
175  break;
176  case ProvideMessage::Code::Redirect: {
177  std::exception_ptr error;
178  DEF_REQ_FIELD(new_url);
179  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
180  REQ_FIELD_CHECK ( Redirect, new_url, std::string )
181  return true;
182  });
183  FAIL_IF_NOT_SEEN_REQ_FIELD( Redirect, new_url );
184  FAIL_IF_ERROR();
185  break;
186  }
187  case ProvideMessage::Code::Metalink: {
188  std::exception_ptr error;
189  DEF_REQ_FIELD(new_url);
190  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
191  REQ_FIELD_CHECK ( Metalink, new_url, std::string )
192  return true;
193  });
194  FAIL_IF_NOT_SEEN_REQ_FIELD( Metalink, new_url );
195  FAIL_IF_ERROR();
196  break;
197  }
198  case ProvideMessage::Code::BadRequest:
199  case ProvideMessage::Code::Unauthorized:
200  case ProvideMessage::Code::Forbidden:
201  case ProvideMessage::Code::PeerCertificateInvalid:
202  case ProvideMessage::Code::NotFound:
203  case ProvideMessage::Code::ExpectedSizeExceeded:
204  case ProvideMessage::Code::ConnectionFailed:
206  case ProvideMessage::Code::Cancelled:
207  case ProvideMessage::Code::InvalidChecksum:
208  case ProvideMessage::Code::MountFailed:
209  case ProvideMessage::Code::Jammed:
210  case ProvideMessage::Code::NoAuthData:
211  case ProvideMessage::Code::MediaChangeAbort:
212  case ProvideMessage::Code::MediaChangeSkip:
213  case ProvideMessage::Code::InternalError: {
214  const auto &e = validateErrorMsg(msg);
215  if ( !e )
216  return e;
217  break;
218  }
219  case ProvideMessage::Code::Provide: {
220  std::exception_ptr error;
221  DEF_REQ_FIELD(url);
222  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
223  REQ_FIELD_CHECK ( Provide, url, std::string )
224  OR_OPT_FIELD_CHECK ( Provide, filename, std::string )
225  OR_OPT_FIELD_CHECK ( Provide, delta_file, std::string )
226  OR_OPT_FIELD_CHECK ( Provide, expected_filesize, int64_t )
227  OR_OPT_FIELD_CHECK ( Provide, check_existance_only, bool )
228  OR_OPT_FIELD_CHECK ( Provide, metalink_enabled, bool )
229  return true;
230  });
232  FAIL_IF_ERROR();
233  break;
234  }
235  case ProvideMessage::Code::Cancel:
236  /* No Fields */
237  break;
238 
239  case ProvideMessage::Code::Attach: {
240  std::exception_ptr error;
241 
242  DEF_REQ_FIELD(url);
243  DEF_REQ_FIELD(attach_id);
244  DEF_REQ_FIELD(label);
245 
246  // not really required, but this way we can check if all false or all true
247  DEF_REQ_FIELD(verify_type);
248  DEF_REQ_FIELD(verify_data);
249  DEF_REQ_FIELD(media_nr);
250 
251  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
252  REQ_FIELD_CHECK ( Attach, url , std::string )
253  OR_REQ_FIELD_CHECK ( Attach, attach_id , std::string )
254  OR_REQ_FIELD_CHECK ( Attach, label , std::string )
255  OR_REQ_FIELD_CHECK ( Attach, verify_type, std::string )
256  OR_REQ_FIELD_CHECK ( Attach, verify_data, std::string )
257  OR_REQ_FIELD_CHECK ( Attach, media_nr , int32_t )
258  OR_OPT_FIELD_CHECK ( Attach, device , std::string )
259  return true;
260  });
263  FAIL_IF_NOT_SEEN_REQ_FIELD( Provide, attach_id );
264  if ( ! ( ( has_verify_data == has_verify_type ) && ( has_verify_type == has_media_nr ) ) )
265  return expected<void>::error( ZYPP_EXCPT_PTR ( InvalidMessageReceivedException("Error in Attach message, one of the following fields is not set or invalid: ( verify_type, verify_data, media_nr ). Either none or all need to be set. ")) );
266  FAIL_IF_ERROR();
267  break;
268  }
269  case ProvideMessage::Code::Detach: {
270  std::exception_ptr error;
271  DEF_REQ_FIELD(url);
272  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
273  REQ_FIELD_CHECK ( Detach, url, std::string )
274  return true;
275  });
276  FAIL_IF_NOT_SEEN_REQ_FIELD( Detach, url );
277  FAIL_IF_ERROR();
278  break;
279  }
280  case ProvideMessage::Code::AuthDataRequest: {
281  std::exception_ptr error;
282  DEF_REQ_FIELD(effective_url);
283  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
284  REQ_FIELD_CHECK ( AuthDataRequest, effective_url, std::string )
285  OR_OPT_FIELD_CHECK ( AuthDataRequest, last_auth_timestamp, int64_t )
286  OR_OPT_FIELD_CHECK ( AuthDataRequest, username, std::string )
287  OR_OPT_FIELD_CHECK ( AuthDataRequest, authHint, std::string )
288  return true;
289  });
290  FAIL_IF_NOT_SEEN_REQ_FIELD( AuthDataRequest, effective_url );
291  FAIL_IF_ERROR();
292  break;
293  }
294  case ProvideMessage::Code::MediaChangeRequest: {
295  std::exception_ptr error;
296  DEF_REQ_FIELD(label);
297  DEF_REQ_FIELD(media_nr);
299  msg.forEachVal( [&]( const auto &name, const ProvideMessage::FieldVal &val ){
300  REQ_FIELD_CHECK ( MediaChangeRequest, label, std::string )
301  OR_REQ_FIELD_CHECK ( MediaChangeRequest, media_nr, int32_t )
302  OR_REQ_FIELD_CHECK ( MediaChangeRequest, device, std::string )
303  OR_OPT_FIELD_CHECK ( MediaChangeRequest, desc, std::string )
304  return true;
305  });
306  FAIL_IF_NOT_SEEN_REQ_FIELD( MediaChangeRequest, label );
307  FAIL_IF_NOT_SEEN_REQ_FIELD( MediaChangeRequest, media_nr );
308  FAIL_IF_NOT_SEEN_REQ_FIELD( MediaChangeRequest, device );
309  FAIL_IF_ERROR();
310  break;
311  }
312  default: {
313  // all error messages have the same format
314  if ( c >= ProvideMessage::Code::FirstClientErrCode && c <= ProvideMessage::Code::LastSrvErrCode ) {
315  const auto &e = validateErrorMsg(msg);
316  if ( !e )
317  return e;
318  }
319  break;
320  }
321  }
322  return expected<void>::success();
323  }
324 
326  : _impl ( new zypp::proto::ProvideMessage )
327  { }
328 
329  expected<zyppng::ProvideMessage> ProvideMessage::create(const RpcMessage &message)
330  {
331  ProvideMessage msg;
332  const auto &res = RpcMessageStream::parseMessageInto<zypp::proto::ProvideMessage>( message, *msg._impl );
333  if ( res ) {
334  const auto &valid = validateMessage(msg);
335  if ( !valid ) {
336  ERR << "Invalid message for ID: " << msg._impl->request_id() << std::endl;;
337  return zyppng::expected<zyppng::ProvideMessage>::error( valid.error() );
338  }
339 
340  return zyppng::expected<zyppng::ProvideMessage>::success( std::move(msg) );
341  }
342  ERR << "Failed to parse message" << std::endl;;
343  return zyppng::expected<zyppng::ProvideMessage>::error( res.error() );
344  }
345 
346  expected<ProvideMessage> ProvideMessage::create( const zypp::proto::ProvideMessage &message )
347  {
348  ProvideMessage msg;
349  *msg._impl = std::move(message);
350  const auto &valid = validateMessage(msg);
351  if ( !valid ) {
352  ERR << "Invalid message for ID: " << msg._impl->request_id() << std::endl;;
353  return zyppng::expected<zyppng::ProvideMessage>::error( valid.error() );
354  }
355 
356  return zyppng::expected<zyppng::ProvideMessage>::success( std::move(msg) );
357  }
358 
359  ProvideMessage ProvideMessage::createProvideStarted( const uint32_t reqId, const zypp::Url &url, const std::optional<std::string> &localFilename, const std::optional<std::string> &stagingFilename )
360  {
361  ProvideMessage msg;
362  msg.setCode ( ProvideMessage::Code::ProvideStarted );
363  msg.setRequestId ( reqId );
365  if ( localFilename )
366  msg.setValue ( ProvideStartedMsgFields::LocalFilename, *localFilename );
367  if ( stagingFilename )
368  msg.setValue ( ProvideStartedMsgFields::StagingFilename, *stagingFilename );
369 
370  return msg;
371  }
372 
373  ProvideMessage ProvideMessage::createProvideFinished( const uint32_t reqId, const std::string &localFilename, bool cacheHit )
374  {
375  ProvideMessage msg;
376  msg.setCode ( ProvideMessage::Code::ProvideFinished );
377  msg.setRequestId ( reqId );
378  msg.setValue ( ProvideFinishedMsgFields::LocalFilename, localFilename );
380 
381  return msg;
382  }
383 
385  {
386  ProvideMessage msg;
387  msg.setCode ( ProvideMessage::Code::AttachFinished );
388  msg.setRequestId ( reqId );
389 
390  return msg;
391  }
392 
394  {
395  ProvideMessage msg;
396  msg.setCode ( ProvideMessage::Code::DetachFinished );
397  msg.setRequestId ( reqId );
398 
399  return msg;
400  }
401 
402  ProvideMessage ProvideMessage::createAuthInfo( const uint32_t reqId, const std::string &user, const std::string &pw, int64_t timestamp, const std::map<std::string, std::string> &extraValues )
403  {
404  ProvideMessage msg;
405  msg.setCode ( ProvideMessage::Code::AuthInfo );
406  msg.setRequestId ( reqId );
409  msg.setValue ( AuthInfoMsgFields::AuthTimestamp, timestamp );
410  for ( auto i : extraValues ) {
411  msg.setValue( i.first, i.second );
412  }
413  return msg;
414  }
415 
417  {
418  ProvideMessage msg;
419  msg.setCode ( ProvideMessage::Code::MediaChanged );
420  msg.setRequestId ( reqId );
421 
422  return msg;
423  }
424 
425  ProvideMessage ProvideMessage::createRedirect( const uint32_t reqId, const zypp::Url &newUrl )
426  {
427  ProvideMessage msg;
428  msg.setCode ( ProvideMessage::Code::Redirect );
429  msg.setRequestId ( reqId );
431 
432  return msg;
433  }
434 
435  ProvideMessage ProvideMessage::createMetalinkRedir( const uint32_t reqId, const std::vector<zypp::Url> &newUrls )
436  {
437  ProvideMessage msg;
438  msg.setCode ( ProvideMessage::Code::Metalink );
439  msg.setRequestId ( reqId );
440  for( const auto &val : newUrls )
441  msg.addValue( MetalinkRedirectMsgFields::NewUrl, val.asCompleteString() );
442 
443  return msg;
444  }
445 
446  ProvideMessage ProvideMessage::createErrorResponse( const uint32_t reqId, const uint code, const std::string &reason, bool transient )
447  {
448  ProvideMessage msg;
449  if ( code < Code::FirstClientErrCode || code > Code::LastSrvErrCode )
450  ZYPP_THROW(std::out_of_range("code must be between 400 and 599"));
451  msg.setCode ( code );
452  msg.setRequestId ( reqId );
453  msg.setValue ( ErrMsgFields::Reason, reason );
454  msg.setValue ( ErrMsgFields::Transient, transient );
455  return msg;
456  }
457 
458  ProvideMessage ProvideMessage::createProvide( const uint32_t reqId, const zypp::Url &url, const std::optional<std::string> &filename, const std::optional<std::string> &deltaFile, const std::optional<int64_t> &expFilesize, bool checkExistOnly )
459  {
460  ProvideMessage msg;
461  msg.setCode ( ProvideMessage::Code::Provide );
462  msg.setRequestId ( reqId );
464 
465  if ( filename )
466  msg.setValue ( ProvideMsgFields::Filename, *filename );
467  if ( deltaFile )
468  msg.setValue ( ProvideMsgFields::DeltaFile, *deltaFile );
469  if ( expFilesize )
470  msg.setValue ( ProvideMsgFields::ExpectedFilesize, *expFilesize );
471  msg.setValue ( ProvideMsgFields::CheckExistOnly, checkExistOnly );
472 
473  return msg;
474  }
475 
477  {
478  ProvideMessage msg;
479  msg.setCode ( ProvideMessage::Code::Cancel );
480  msg.setRequestId ( reqId );
481 
482  return msg;
483  }
484 
485  ProvideMessage ProvideMessage::createAttach(const uint32_t reqId, const zypp::Url &url, const std::string attachId, const std::string &label, const std::optional<std::string> &verifyType, const std::optional<std::string> &verifyData, const std::optional<int32_t> &mediaNr )
486  {
487  ProvideMessage msg;
488  msg.setCode ( ProvideMessage::Code::Attach );
489  msg.setRequestId ( reqId );
491  msg.setValue ( AttachMsgFields::AttachId, attachId );
492  msg.setValue ( AttachMsgFields::Label, label );
493 
494  if ( verifyType.has_value() && verifyData.has_value() && mediaNr.has_value() ) {
495  msg.setValue ( AttachMsgFields::VerifyType, *verifyType );
496  msg.setValue ( AttachMsgFields::VerifyData, *verifyData );
497  msg.setValue ( AttachMsgFields::MediaNr, *mediaNr );
498  } else {
499  if ( !( ( verifyType.has_value() == verifyData.has_value() ) && ( verifyData.has_value() == mediaNr.has_value() ) ) )
500  WAR << "Attach message requires verifyType, verifyData and mediaNr either set together or not set at all." << std::endl;
501  }
502 
503  return msg;
504  }
505 
506  ProvideMessage ProvideMessage::createDetach( const uint32_t reqId, const zypp::Url &attachUrl )
507  {
508  ProvideMessage msg;
509  msg.setCode ( ProvideMessage::Code::Detach );
510  msg.setRequestId ( reqId );
511  msg.setValue ( DetachMsgFields::Url, attachUrl.asCompleteString() );
512 
513  return msg;
514  }
515 
516  ProvideMessage ProvideMessage::createAuthDataRequest( const uint32_t reqId, const zypp::Url &effectiveUrl, const std::string &lastTriedUser, const std::optional<int64_t> &lastAuthTimestamp, const std::map<std::string, std::string> &extraValues )
517  {
518  ProvideMessage msg;
519  msg.setCode ( ProvideMessage::Code::AuthDataRequest );
520  msg.setRequestId ( reqId );
522  if ( lastTriedUser.size() )
523  msg.setValue( AuthDataRequestMsgFields::LastUser, lastTriedUser );
524  if ( lastAuthTimestamp )
525  msg.setValue ( AuthDataRequestMsgFields::LastAuthTimestamp, *lastAuthTimestamp );
526 
527  return msg;
528  }
529 
530  ProvideMessage ProvideMessage::createMediaChangeRequest( const uint32_t reqId, const std::string &label, int32_t mediaNr, const std::vector<std::string> &devices, const std::optional<std::string> &desc )
531  {
532  ProvideMessage msg;
533  msg.setCode ( ProvideMessage::Code::MediaChangeRequest );
534  msg.setRequestId ( reqId );
537  for ( const auto &device : devices )
539  if ( desc )
541 
542  return msg;
543  }
544 
546  {
547  return _impl->request_id();
548  }
549 
550  void ProvideMessage::setRequestId(const uint id)
551  {
552  _impl->set_request_id( id );
553  }
554 
555  uint ProvideMessage::code() const
556  {
557  return _impl->message_code();
558  }
559 
560  void ProvideMessage::setCode( const uint newCode )
561  {
562  _impl->set_message_code ( newCode );
563  }
564 
565  std::vector<ProvideMessage::FieldVal> ProvideMessage::values( const std::string_view &str ) const
566  {
567  std::vector<ProvideMessage::FieldVal> values;
568  const auto &fields = _impl->fields();
569  for ( const auto &field : fields ) {
570  if ( field.key() != str )
571  continue;
572  values.push_back( fieldValFromProto(field) );
573  }
574  return values;
575  }
576 
577  std::vector<ProvideMessage::FieldVal> ProvideMessage::values( const std::string &str ) const
578  {
579  return values( std::string_view(str));
580  }
581 
582  ProvideMessage::FieldVal ProvideMessage::value( const std::string_view &str, const FieldVal &defaultVal ) const
583  {
584  const auto &fields = _impl->fields();
585  auto i = std::find_if( fields.rbegin(), fields.rend(), [&str]( const auto &val ){ return val.key() == str; } );
586  if ( i == fields.rend() )
587  return defaultVal;
588  return fieldValFromProto(*i);
589  }
590 
591 
593  {
594  HeaderValueMap res;
595  auto &fields = _impl->fields();
596  for ( const auto &val : fields ) {
597  res.add( val.key() ,fieldValFromProto(val) );
598  }
599  return res;
600  }
601 
602  ProvideMessage::FieldVal ProvideMessage::value( const std::string &str, const FieldVal &defaultVal ) const
603  {
604  return value( std::string_view(str), defaultVal );
605  }
606 
607  void ProvideMessage::setValue( const std::string &name, const FieldVal &value )
608  {
609  setValue( std::string_view(name), value );
610  }
611 
612  void ProvideMessage::setValue( const std::string_view &name, const FieldVal &value )
613  {
614  auto &fields = *_impl->mutable_fields();
615  auto i = std::find_if( fields.rbegin(), fields.rend(), [&name]( const auto &val ){ return val.key() == name; } );
616  if ( i == fields.rend() ) {
617  auto &newVal = *_impl->add_fields();
618  newVal.set_key( name.data() );
619  fieldValToProto( value, newVal );
620  } else
621  fieldValToProto( value, *i );
622  }
623 
624  void ProvideMessage::addValue( const std::string &name, const FieldVal &value )
625  {
626  return addValue( std::string_view(name), value );
627  }
628 
629  void ProvideMessage::addValue( const std::string_view &name, const FieldVal &value )
630  {
631  auto &newVal = *_impl->add_fields();
632  newVal.set_key( name.data() );
633  fieldValToProto( value, newVal );
634  }
635 
636  void ProvideMessage::forEachVal( const std::function<bool (const std::string &, const FieldVal &)> &cb ) const
637  {
638  auto &fields = _impl->fields();
639  for ( const auto &val : fields ) {
640  if ( !cb( val.key(), fieldValFromProto(val) ) ) {
641  return;
642  }
643  }
644  }
645 
646  zypp::proto::ProvideMessage &ProvideMessage::impl()
647  {
648  return *_impl.get();
649  }
650 
651  const zypp::proto::ProvideMessage &ProvideMessage::impl() const
652  {
653  return *_impl.get();
654  }
655 
656 }
static ProvideMessage createErrorResponse(const uint32_t reqId, const uint code, const std::string &reason, bool transient=false)
void add(const std::string &key, const Value &val)
constexpr std::string_view Url("url")
constexpr std::string_view LocalFilename("local_filename")
const std::string & asString() const
bool isDouble() const
constexpr std::string_view AttachId("attach_id")
static void fieldValToProto(const ProvideMessage::FieldVal &val, zypp::proto::DataField &field)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
zypp::RWCOW_pointer< zypp::proto::ProvideMessage > _impl
void forEachVal(const std::function< bool(const std::string &name, const FieldVal &val)> &cb) const
constexpr std::string_view VerifyData("verify_data")
static ProvideMessage createMetalinkRedir(const uint32_t reqId, const std::vector< zypp::Url > &newUrls)
static ProvideMessage createProvide(const uint32_t reqId, const zypp::Url &url, const std::optional< std::string > &filename={}, const std::optional< std::string > &deltaFile={}, const std::optional< int64_t > &expFilesize={}, bool checkExistOnly=false)
constexpr std::string_view Filename("filename")
static ProvideMessage::FieldVal fieldValFromProto(const zypp::proto::DataField &field)
static ProvideMessage createAuthInfo(const uint32_t reqId, const std::string &user, const std::string &pw, int64_t timestamp, const std::map< std::string, std::string > &extraValues={})
HeaderValueMap headers() const
static ProvideMessage createAttach(const uint32_t reqId, const zypp::Url &url, const std::string attachId, const std::string &label, const std::optional< std::string > &verifyType={}, const std::optional< std::string > &verifyData={}, const std::optional< int32_t > &mediaNr={})
#define DEF_REQ_FIELD(fname)
static ProvideMessage createMediaChanged(const uint32_t reqId)
String related utilities and Regular expression matching.
constexpr std::string_view MediaNr("media_nr")
static ProvideMessage createAttachFinished(const uint32_t reqId)
#define FAIL_IF_NOT_SEEN_REQ_FIELD(msgtype, fname)
constexpr std::string_view VerifyType("verify_type")
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition: Exception.h:432
void addValue(const std::string &name, const FieldVal &value)
constexpr std::string_view Label("label")
#define FAIL_IF_ERROR()
bool isString() const
#define ERR
Definition: Logger.h:98
static ProvideMessage createProvideStarted(const uint32_t reqId, const zypp::Url &url, const std::optional< std::string > &localFilename={}, const std::optional< std::string > &stagingFilename={})
constexpr std::string_view Password("password")
constexpr std::string_view Username("username")
int64_t asInt64() const
constexpr std::string_view CheckExistOnly("check_existance_only")
constexpr std::string_view NewUrl("new_url")
constexpr std::string_view LocalFilename("local_filename")
FieldVal value(const std::string_view &str, const FieldVal &defaultVal=FieldVal()) const
constexpr std::string_view LastAuthTimestamp("last_auth_timestamp")
std::vector< FieldVal > values(const std::string_view &str) const
constexpr std::string_view Device("device")
constexpr std::string_view Label("label")
#define WAR
Definition: Logger.h:97
std::string asCompleteString() const
Returns a complete string representation of the Url object.
Definition: Url.cc:505
constexpr std::string_view MediaNr("media_nr")
static ProvideMessage createAuthDataRequest(const uint32_t reqId, const zypp::Url &effectiveUrl, const std::string &lastTriedUser="", const std::optional< int64_t > &lastAuthTimestamp={}, const std::map< std::string, std::string > &extraValues={})
static ProvideMessage createDetach(const uint32_t reqId, const zypp::Url &attachUrl)
constexpr std::string_view Reason("reason")
static ProvideMessage createRedirect(const uint32_t reqId, const zypp::Url &newUrl)
constexpr std::string_view NewUrl("new_url")
void setValue(const std::string &name, const FieldVal &value)
constexpr std::string_view DeltaFile("delta_file")
constexpr std::string_view EffectiveUrl("effective_url")
constexpr std::string_view Transient("transient")
constexpr std::string_view AuthTimestamp("auth_timestamp")
#define OR_REQ_FIELD_CHECK(msgtype, fname, ftype)
void setCode(const uint newCode)
void setRequestId(const uint id)
bool isInt64() const
static ProvideMessage createCancel(const uint32_t reqId)
constexpr std::string_view Url("url")
static ProvideMessage createProvideFinished(const uint32_t reqId, const std::string &localFilename, bool cacheHit)
constexpr std::string_view Url("url")
int32_t asInt() const
static expected< void > validateMessage(const ProvideMessage &msg)
constexpr std::string_view device("device")
constexpr std::string_view StagingFilename("staging_filename")
const D * get() const
Definition: PtrTypes.h:503
#define REQ_FIELD_CHECK(msgtype, fname, ftype)
constexpr std::string_view Url("url")
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::proto::ProvideMessage & impl()
static expected< ProvideMessage > create(const zyppng::RpcMessage &message)
constexpr std::string_view Desc("desc")
static ProvideMessage createDetachFinished(const uint32_t reqId)
double asDouble() const
#define OR_OPT_FIELD_CHECK(msgtype, fname, ftype)
constexpr std::string_view CacheHit("cacheHit")
constexpr std::string_view LastUser("username")
Url manipulation class.
Definition: Url.h:91
static ProvideMessage createMediaChangeRequest(const uint32_t reqId, const std::string &label, int32_t mediaNr, const std::vector< std::string > &devices, const std::optional< std::string > &desc)
constexpr std::string_view ExpectedFilesize("expected_filesize")