Changeset 229
- Timestamp:
- 12/09/06 14:41:39 (2 years ago)
- Files:
-
- branches/message-handling-refactor-branch/bin/run-command-center.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/bin/run-copy-directive-n.sh (modified) (1 diff)
- branches/message-handling-refactor-branch/src/hefeweizen_big_ania.rb (modified) (12 diffs)
- branches/message-handling-refactor-branch/src/hefeweizen_library_b2b_system.rb (modified) (2 diffs)
- branches/message-handling-refactor-branch/src/hefeweizen_library_directive.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/src/hefeweizen_library_ebMS_message2.rb (modified) (14 diffs)
- branches/message-handling-refactor-branch/src/hefeweizen_library_transactions.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/src/taskers/hefeweizen_tasker_application_send_ebXML_message.rb (modified) (5 diffs)
- branches/message-handling-refactor-branch/src/taskers/hefeweizen_tasker_system_tasker_monitor.sh (modified) (1 diff)
- branches/message-handling-refactor-branch/test/tools/hefeweizen_tool_tester.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/test/unit-tests/tc_hefeweizen_library_cpa_test.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/test/unit-tests/tc_hefeweizen_library_ebMS_message_test.rb (modified) (16 diffs)
- branches/message-handling-refactor-branch/test/unit-tests/tc_hefeweizen_library_transactions_test.rb (modified) (1 diff)
- branches/message-handling-refactor-branch/test/various/sending_lots_of_pings.rb (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/message-handling-refactor-branch/bin/run-command-center.rb
r181 r229 247 247 { :type => "urn:li.coronation.b2b", :id => "coronation_test_system"} ] 248 248 249 cpas_info = [cpa.setup_all_ebMS_header_infos cpa.id, party_name, party_identities]249 cpas_info = [cpa.setup_all_ebMS_header_infos( cpa.id, party_name, party_identities )] 250 250 number_directives = work_directive_dynamic_menu cpas_info, number_directives 251 251 when "S" branches/message-handling-refactor-branch/bin/run-copy-directive-n.sh
r207 r229 10 10 cp "../test/sample-directives/directive_send_invoice_cpa_id_Coronation::Gnaraloo::UBL 1.0 Invoice Notification.xml" /tmp/test 11 11 su hefeweizen -c "cp \"../test/sample-directives/directive_send_invoice_cpa_id_Coronation::Gnaraloo::UBL 1.0 Invoice Notification.xml\" /var/spool/hefeweizen/coronation/outgoing/directives/directive_invoice_$UUID1_$UUID1" 12 sleep 0. 1212 sleep 0.2 13 13 done 14 14 branches/message-handling-refactor-branch/src/hefeweizen_big_ania.rb
r227 r229 414 414 @logger.debug "Received new directive!" 415 415 if !transaction.open_and_new? then 416 @logger.warn "A transaction must be new and open for a new directive." 416 @logger.warn "A transaction must be new and open for command '#{command}'." 417 return false 417 418 else 418 419 result = process_new_directive2 command, command_hash, transaction … … 426 427 @logger.debug "Successfully processed new directive." 427 428 @logger.debug "Its time to deliver the ebXML message." 428 return deliver( transaction ) 429 command, expectation = start_delivery( transaction, command_hash['b2b_system_name'] ) 430 transaction.set_next_expectation(expectation) 431 say_to_ania command 432 return true 429 433 elsif result == false then 430 434 @logger.debug "Problems processing new directive xx." 431 # ??? 435 # ??? what TODO? 436 return false 432 437 end 433 438 elsif result.class == String then … … 436 441 else 437 442 @logger.warn "Problems processing new directive: #{result}" 438 # ??? 443 # ??? what TODO? 444 return false 439 445 end 440 446 end … … 457 463 end 458 464 @logger.debug "Its time to deliver the ebXML message." 459 460 return deliver( transaction ) 465 command, expectation = start_delivery( transaction, command_hash['b2b_system_name'] ) 466 transaction.set_next_expectation(expectation) 467 say_to_ania command 468 return true 461 469 462 470 elsif command == 'encrypt ebXML message done' then … … 464 472 transaction.transition_to_new_state "encrypt ebXML message done" 465 473 @logger.debug "Its time to deliver the ebXML message." 466 return deliver( transaction ) 467 468 else 469 puts "I dont know what the fuck to do with #{command}" 470 end 471 474 command, expectation = start_delivery( transaction, command_hash['b2b_system_name'] ) 475 transaction.set_next_expectation(expectation) 476 say_to_ania command 477 return true 478 479 elsif command == 'start ebXML message delivery' then 480 @logger.debug "Received start ebXML message delivery command." 481 @logger.debug "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx this far is OK" 482 return true 483 transaction.transition_to_new_state command 484 ebXML_message_id = transaction.get_ebXML_message_reference 485 if !ebXML_message_id.nil? 486 @logger.debug "Start of delivery of ebXML message with id: #{ebXML_message_id}" 487 command, expectation = deliver_ebXML_message transaction, ebXML_message_id, command_hash['b2b_system_name'] 488 if command == false then 489 msg = "It is not possible to start the delivery process." 490 @logger.warn msg 491 transaction.fail msg 492 return false 493 else 494 @logger.debug "Start of delivery of ebXML message can start." 495 transaction.set_next_expectation(expectation) 496 say_to_ania command 497 return true 498 end 499 else 500 msg = "Error getting the ebXML message id. Unable to find ebXML message from transaction with id #{transaction.transaction_id}" 501 @logger.debug "Error getting the ebXML message id. Unable to find ebXML message from transaction with id #{transaction.transaction_id}" 502 transaction.fail msg 503 return true 504 end 505 elsif command == 'send ebXML message done' 506 @logger.debug "Send ebXML message done." 507 # this does not yet mean that the message is delivered. This means that the ebXML message made it 508 # to the other side. Things that can happen are 509 # o synchronous or asynchronous ebXML error message for this ebXML message is received. 510 # o an acknowledgment may be required for the ebXML message. 511 @logger.debug 'yesssssssssssssssssssssssss' 512 @logger.debug 'impementation stopps here' 513 elsif command == 'new ebXML message received' then 514 if !transaction.open_and_new? then 515 @logger.warn "A transaction must be new and open for command '#{command}'." 516 return false 517 else 518 @logger.debug "Received new ebXML message!" 519 result = process_new_ebXML_message2 command, command_hash, transaction 520 if result == false then 521 @logger.error "Error processing ebXML Message" 522 transaction.close_transaction('failed', "Failed to process ebXML message.") if transaction.is_open? 523 return false 524 else 525 return true 526 end 527 end 528 else 529 @logger.warn "I dont know what the fuck to do with this '#{command}' command." 530 end 531 532 533 472 534 # if transaction still open and noone processed it ....... I may have to close it. 473 535 474 536 end 475 537 538 def get_ebMS_info ebXML_message_id, b2b_system_name 539 ebXML_message_parameters_file_path = "#{@config['MESSAGE_DIR']}/#{b2b_system_name}/#{ebXML_message_id}/ebXML_message_parameters.yml" 540 return read_ebXML_message_info( ebXML_message_parameters_file_path ) 541 end 542 543 def store_ebMS_info ebMS_info 544 path = "#{ebMS_info['ebXML_message']['ebXML_message_dir']}/#{ebMS_info['ebXML_message']['ebXML_message_parameters_file_name']}" 545 file = File.new(path, "w") 546 YAML.dump ebMS_info, file 547 file.close 548 return true 549 end 550 476 551 def read_ebXML_message_info ebXML_message_parameters_file_path 477 552 if (FileTest.exists?(ebXML_message_parameters_file_path) && FileTest.readable?(ebXML_message_parameters_file_path)) then … … 482 557 end 483 558 484 def deliver transaction 559 def deliver_ebXML_message transaction, ebXML_message_id, b2b_system_name 560 ebMS_info = get_ebMS_info ebXML_message_id, b2b_system_name 561 if ebMS_info.nil? then 562 @logger.warn "Problems gettig the ebXML Message Info structore from the message data store for ebXML message with id #{ebXML_message_id}" 563 return false 564 end 565 @logger.debug "Successfully read the ebXML message info structure for ebXML message with id #{ebXML_message_id}." 566 567 # adding delivery informationn to the ebMS_info 568 if ebMS_info['delivery'].nil? then 569 dev = ebMS_info['delivery'] = Hash.new 570 dev['delivery_process_started'] = Time.now.to_s 571 tries = dev['delivery_tries'] = Array.new 572 tries[0] = Time.now.to_s 573 else 574 ebMS_info['delivery']['delivery_tries'] << Time.now.to_s 575 end 576 577 store_ebMS_info ebMS_info 578 579 #call tasker to send ebXML message 580 # SEND ebXML MESSAGE 581 # ------------------ 582 expectation = "send_ebXML_message_done" 583 command_hash = { 584 "from" => "big_ania", 585 "to" => "ania", 586 "command" => "start_tasker", 587 "tasker" => "#{@config['BIN_DIR']}/hefeweizen_tasker_application_send_ebXML_message.rb", 588 "tasker arguments" => "--b2b-system-name #{b2b_system_name} --pipe-to-ania #{@config['PIPE_TO_ANIA']} --config #{@config['CONFIG_DIR']}/hefeweizen.conf --ebXML-message-file-path #{ebMS_info['ebXML_message']['ebXML_message_dir']}/#{ebMS_info['ebXML_message']['ebXML_message_file_name']} --parameters-file-path #{ebMS_info['ebXML_message']['ebXML_message_dir']}/#{ebMS_info['ebXML_message']['ebXML_message_parameters_file_name']} --transaction-id #{transaction.transaction_id} --state-expectation #{expectation}", 589 "uuid" => HefeWeizen::HefeWeizenLibrary::HefeWeizenUUID.uuid 590 } 591 592 @logger.debug "Call tasker to send ebXML message." 593 say_to_ania "#{HefeWeizen::HefeWeizenLibrary::HefeWeizenCommand.hash_to_command command_hash}" 594 595 # SET EXPECTED NEW STATE 596 transaction.set_next_expectation(expectation) 597 598 return true 599 600 601 end 602 603 def delivery_ack_requested? ebMS_info 604 (ebMS_info['info']['mc-ackRequested'] == 'always' or ( ebMS_info['info']['mc-ackRequested'] == 'perMessage' and !ebMS_info['directive']['ackRequested'].nil? ) ) ? true : false 605 end 606 607 def delivery_reliable_messaging_requested? ebMS_info 608 delivery_ack_requested? ebMS_info 609 end 610 611 def start_delivery transaction, b2b_system_name 612 @logger.debug "Lets beam us to the ebXML message deliver state" 485 613 transaction.transition_to_new_state "ebXML message delivery process started" 486 @logger.debug "DELIVER...........:::" 487 transaction.add_comment "YEP cool dude." 488 transaction.succeed "OKEY DUDES. DONE." 489 return true 614 expectation = "start_ebXML_message_delivery" 615 command_hash = { 616 "from" => "big_ania", 617 "to" => "big ania", 618 "b2b_system_name" => b2b_system_name, 619 "command" => "start ebXML message delivery", 620 "transaction_id" => transaction.transaction_id, 621 "uuid" => HefeWeizen::HefeWeizenLibrary::HefeWeizenUUID.uuid 622 } 623 624 command = "#{HefeWeizen::HefeWeizenLibrary::HefeWeizenCommand.hash_to_command command_hash}" 625 return command, expectation 490 626 end 491 627 … … 500 636 begin 501 637 directive = HefeWeizen::HefeWeizenLibrary::HefeWeizenDirective.new(@config, command_hash['file']) 502 # transaction.remember_file_to_remove command_hash['file'] if command_hash['file']503 638 rescue Exception => e 504 639 … … 524 659 @logger.debug "Succesfully stored the directive as root cause" 525 660 end 526 661 662 # TODO have a better validate! 527 663 if !b2b_system.supports_directive? directive then 528 664 @logger.warn "B2BSystem #{b2b_system.system_name} does not support the directive." … … 532 668 begin 533 669 # this creates a plain ebXML message 534 metadata= b2b_system.process_directive directive670 ebMS_info = b2b_system.process_directive directive 535 671 rescue Exception => e 536 672 @logger.warn "B2BSystem #{b2b_system.system_name} is unable to create an ebXML message: #{e.to_s}; #{e.backtrace}" 537 673 return false 538 674 end 539 540 transaction.attach_file metadata['complete_ebXML_message_file_path'], "outgoing ebXML message" 541 transaction.attach_file metadata['complete_ebXML_message_parameters_file_path'], "outgoing ebXML message parameters" 542 543 # a plain ebXML message has been created. 675 676 path = "#{@config['MESSAGE_DIR']}/#{b2b_system.system_name}/#{ebMS_info['ebXML_message']['ebXML_message_id']}" 677 puts complete_ebXML_message_file_path = "#{path}/ebXML_message.ebMS2" 678 puts complete_ebXML_message_parameters_file_path = "#{path}/ebXML_message_parameters.yml" 679 680 transaction.attach_file complete_ebXML_message_file_path, "outgoing ebXML message" 681 transaction.attach_file complete_ebXML_message_parameters_file_path, "outgoing ebXML message parameters" 682 683 # attach the ebXML message to the transaction 544 684 transaction.transition_to_new_state "plain ebXML message created" 685 @logger.debug "Setting ebXML message id '#{ebMS_info['ebXML_message']['ebXML_message_id']}' to transaction." 686 transaction.add_ebXML_message_id_reference ebMS_info['ebXML_message']['ebXML_message_id'] 687 688 # ebXML message is created. 689 # Continue with processing 545 690 546 691 # signing first 547 if ((signing = true) == true) then692 if ((signing = false) == true) then 548 693 @logger.debug "ebXML message must be signed. Starting a signer tasker" 549 694 command, expectation = start_a_signing_tasker metadata, transaction.transaction_id, b2b_system.system_name … … 605 750 end 606 751 607 608 752 # This method receives an ebXML message and starts to process it. 753 def process_new_ebXML_message2 command, command_hash, transaction 754 @logger.debug "Reading received ebXML message." 755 756 # TODO transport dependent header reading 757 # SMTP / HTTP independent 758 ebMS_message_header = File.read(command_hash['file_header']) 759 760 # setting root cause of this new transaction. 761 transaction.set_root_cause command_hash['file_full'] 762 763 # maybe stuff this into ebMS class 764 # SMTP / HTTP independent 765 if !(ebMS_message_header =~ /^.*SOAPAction: ebXML.*$/ or ebMS_message_header =~ /.*SOAPAction: \"ebXML\".*/) then 766 msg = "Received a message but the received message does not have a \"SOAPAction: ebXML\" HTTP header, so it is not an ebXML message." 767 @logger.warn msg 768 transaction.remember_file_to_remove [command_hash['file_full'], command_hash['file_body'], command_hash['file_header']] 769 #?? send_error "Bad Request", transaction, command_hash 770 transaction.close_transaction('failed', msg) 771 return true 772 end 773 @logger.debug "Message header indicates that it is an ebXML message." 774 775 # DUPLICATE! ok for now. -> add link_to in transaction class 776 transaction.attach_file command_hash['file_full'], "incoming ebXML message" 777 778 transaction.remember_file_to_remove command_hash['file_full'] 779 transaction.remember_file_to_remove command_hash['file_body'] 780 transaction.remember_file_to_remove command_hash['file_header'] 781 782 b2b_system = @b2b_systems[command_hash['b2b_system_name']] 783 if b2b_system.nil? then 784 @logger.warn "There is no B2B system with the name #{command_hash['b2b_system_name']}." 785 return false 786 end 787 788 begin 789 @logger.debug "Creating an ebXML message object from the received ebXML message. Provides basic ebXML message parsing." 790 # this parses the incoming message and creates an ebXML message object 791 ebXML_message_object = b2b_system.process_incoming_ebXML_message command_hash 792 if ebXML_message_object.nil? then 793 @logger.warn "Error creating an ebXML object from the ebXML message from file #{command_hash['file_full']}." 794 return false 795 end 796 @logger.debug "Successfully created ebXML message object: #{ebXML_message_object.summary}" 797 rescue Exception => e 798 msg = "It is not possible to create an ebXML Message object from the incoming ebXML message: #{e.to_s}" 799 @logger.warn msg 800 #?? send_error "Bad Request", transaction, command_hash 801 transaction.close_transaction('failed', msg) 802 return true 803 end 804 805 puts 'yesssssssssssssssssssssssss ebxml message processed.' 806 807 # decrypt 808 809 # validate signature 810 811 # start delivery job 812 813 end 609 814 610 815 … … 617 822 618 823 619 824 620 825 621 826 … … 1165 1370 end 1166 1371 1167 # This method validates an ebXML message.1168 def validate_ebXML_message command_hash, ebMS_message1169 1170 b2b_system = @b2b_systems[command_hash['b2b_system_name']]1171 if b2b_system.nil? then1172 error = HefeWeizen::HefeWeizenLibrary::EBMSError.new "", "There is no party with the name #{command_hash['b2b_system_name']}."1173 @logger.warn error1174 return false, nil, [error]1175 end1176 1177 cpa = b2b_system.get_cpa ebMS_message.cpa_id1178 if cpa.nil? then1179 error = HefeWeizen::HefeWeizenLibrary::EBMSError.new "","There is no CPA with id #{ebMS_message.cpa_id} for b2b_system with the name #{b2b_system.system_name}."1180 @logger.warn error1181 return false, nil, [error]1182 end1183 1184 hash_value = ebMS_message.get_hash_value cpa1185 1186 info_structure = cpa.get_ebMS_info_structure_for_hash_value hash_value1187 if info_structure.nil? then1188 error = HefeWeizen::HefeWeizenLibrary::EBMSError.new "","There is no Service '#{ebMS_message.service}' and Action '#{ebMS_message.action}' for this two PartyId's (sender #{ebMS_message.from_name} with type #{ebMS_message.from_type} and receiver #{ebMS_message.to_name} with type #{ebMS_message.to_type} ) in the ebXML CPA with id #{ebMS_message.cpa_id}."1189 @logger.warn error1190 return false, nil, [error]1191 else1192 # checks:1193 # o from party and to party OK?1194 # --> already checked when looking up possilble incoming messages1195 # o ack requested ?1196 # o signature requested ?1197 # o encryption requested ?1198 1199 error_messages = Array.new1200 1201 if !ebMS_message.is_ebMS_signal? then1202 if info_structure['info']['mc-ackRequested'] == 'always' and !ebMS_message.ack_requested? then1203 require 'pp'1204 pp info_structure['info']1205 pp ebMS_message.to_s1206 error_messages << ( HefeWeizen::HefeWeizenLibrary::EBMSError.new "", "CPA says message must acknowledged but ebXML message does not include the Request for an Acknowledgment. This is a contradiction." )1207 elsif info_structure['info']['mc-ackRequested'] == 'never' and ebMS_message.ack_requested? then1208 error_messages << ( HefeWeizen::HefeWeizenLibrary::EBMSError.new "", "CPA says message must not never be acknowledged but ebXML message does include the Request for an Acknowledgment. This is a conradiction." )1209 end1210 end1211 1212 # TODO1213 # Reliable Messaging1214 # o check duplicate elimination1215 # --> lookup message id1216 # fill validation_errors1217 1218 # TODO1219 # Decrypt if encrypted $1220 # --> needs to be done in the EBMSMesage constructor? so that the payloads can be decrypted?1221 # --> maybe if the payloads are encrypted the EBMSMessage constructor should not unpackage the payloads but1222 # have a special method for it and that method would be called now.1223 # fill validation_errors1224 1225 # TODO1226 # Validate signature if signed1227 # fill validation_errors1228 1229 @logger.debug "ebMS Message check not yet completely implemented."1230 if !error_messages.empty? then1231 msg = error_messages.join("\n")1232 @logger.warn msg1233 return false, nil, error_messages1234 end1235 end1236 return true, info_structure, []1237 end1238 1372 1239 1373 end branches/message-handling-refactor-branch/src/hefeweizen_library_b2b_system.rb
r227 r229 174 174 end 175 175 176 # create a plain ebXML message 176 177 @logger.debug "Creating plain (not signed not encrypted) ebXML message" 177 metadata = @ebMS_message_manager.create_ plain_message directive, ebMS_message_info178 metadata = @ebMS_message_manager.create_ebXML_message_file directive, ebMS_message_info 178 179 if metadata.nil? then 179 180 throw Exception.new( "Error creating ebXML message" ) … … 181 182 @logger.debug "Creating ebXML message done. ebXML message is created." 182 183 183 return metadata 184 # update metadata about ebXML message 185 # ----------------------------------- 186 187 #add information about actual ebXML message to ebMS info 188 dev = ebMS_message_info['ebXML_message'] = Hash.new 189 dev['ebXML_message_id'] = metadata['ebXML_message_id'] 190 dev['ebXML_message_conversation_id'] = metadata['ebXML_message_conversation_id'] 191 192 # add directive stuff to ebMS_info 193 directive_info = ebMS_message_info['directive'] = Hash.new 194 directive_info.merge! directive.tags 195 196 # create the parameters file for the ebXML message. 197 ebMS_info_file_path = ebMS_info_to_temp_file ebMS_message_info 198 199 # add the message and parameters file to the message store. 200 @logger.debug "Adding the created ebXML message and parameters file to the message store." 201 202 directory = @ebMS_message_manager.add_ebXML_message_file_to_message_store system_name, metadata 203 if directory.nil? then 204 @logger.warn "Error adding ebXML message with id '#{metadata['ebXML_message_id']}' to message store." 205 return nil 206 end 207 208 success = @ebMS_message_manager.add_ebXML_message_info_file_to_message_store system_name, directory, ebMS_info_file_path 209 if success.nil? then 210 @logger.warn "Error storing ebXML message parameters file to message store along with message with id '#{metadata['ebXML_message_id']}'." 211 return nil 212 end 213 return ebMS_message_info 214 end 215 216 def ebMS_info_to_temp_file ebMS_info 217 path = "#{@config['TEMP_FILE_DIR']}/ebMS_info__#{Time.now.to_f.to_s}_#{Time.now.to_f.to_s}" 218 file = File.new(path, "w") 219 YAML.dump ebMS_info, file 220 file.close 221 return path 222 end 223 224 def store_ebMS_info ebMS_info 225 path = "#{ebMS_info['ebXML_message']['ebXML_message_dir']}/#{ebMS_info['ebXML_message']['ebXML_message_parameters_file_name']}" 226 file = File.new(path, "w") 227 YAML.dump ebMS_info, file 228 file.close 229 return true 230 end 231 232 # This method processes an incoming ebXML message 233 def process_incoming_ebXML_message command_hash 234 if command_hash.nil? then 235 @logger.warn "The command hash is null." 236 return nil 237 end 238 239 # 1. create an ebXML message object 240 ebXML_message_object = @ebMS_message_manager.create_ebXML_message_object_from_file command_hash['file_full'] 241 if ebXML_message_object.nil? then 242 @logger.warn "Unable to create an ebXML message object from the command_hash" 243 return nil 244 end 245 @logger.debug "Successfully create an ebXML object from the incoming ebXML message. ebXML message is not yet added to the message store." 246 247 # 1. validate whether it is OK to receive such an ebXML message 248 ok, ebMS_info, validation_errors = validate_ebXML_message command_hash, ebMS_message_object 249 if ok.nil? or ok == false then 250 msg = "Based on ebXML CPA it is not possible to receive this ebXML message(#{ebMS_message.summary})" 251 msg += validation_errors.join("\n") 252 @logger.warn msg 253 return nil 254 end 255 @logger.debug "The CPA confirms that it is possible to recive such an ebXML message (summary: #{ebMS_message_object.summary})." 256 257 # def add_ebXML_message_and_parameters_file_to_message_store b2b_system_name, metadata_about_ebXML_message, ebXML_message_parameters_file_path 258 259 meatadata = { 260 'temp_ebXML_message_file_path' => ebMS_message_object.raw_message_file_path, 261 'ebXML_message_id' => ebMS_message_object.message_id, 262 'conversation_id' => ebMS_message_object.conversation_id 263 } 264 265 parameters_file_path = "#{@config['TEMP_FILE_DIR']}/params_file_#{Time.now.to_f.to_s}_#{Time.now.to_f.to_s}" 266 file = File.new parameters_file_path, "w" 267 YAML.dump ebMS_info, file 268 file.close 269 270 complete_ebXML_message_file_path = @ebMS_message_manager.add_ebXML_message_and_parameters_file_to_message_store(system_name, 271 metadata, 272 parameters_file_path) 273 274 FileUtils.rm parameters_file_path 275 FileUtils.rm ebXML_message_object, @raw_message_file_path 276 277 if complete_ebXML_message_file_path.nil? then 278 throw Exception.new( "Error storing the ebXML message in the message store." ) 279 end 280 281 return ebXML_message_object.message_id 184 282 end 185 283 186 284 private 187 285 188 286 # This method validates an ebXML message. 287 # --> this includes to valdiate the ebXML message against the CPA. 288 def validate_ebXML_message command_hash, ebMS_message 289 290 cpa = get_cpa ebMS_message.cpa_id 291 if cpa.nil? then 292 error = HefeWeizen::HefeWeizenLibrary::EBMSError.new "","There is no CPA with id #{ebMS_message.cpa_id} for b2b_system with the name #{b2b_system.system_name}." 293 @logger.warn error 294 return false, nil, [error] 295 end 296 297 hash_value = ebMS_message.get_hash_value cpa 298 299 info_structure = cpa.get_ebMS_info_structure_for_hash_value hash_value 300 if info_structure.nil? then 301 error = HefeWeizen::HefeWeizenLibrary::EBMSError.new "","There is no Service '#{ebMS_message.service}' and Action '#{ebMS_message.action}' for this two PartyId's (sender #{ebMS_message.from_name} with type #{ebMS_message.from_type} and receiver #{ebMS_message.to_name} with type #{ebMS_message.to_type} ) in the ebXML CPA with id #{ebMS_message.cpa_id}." 302 @logger.warn error 303 return false, nil, [error] 304 else 305 306 # checks: 307 # o from party and to party OK? 308 # --> already checked when looking up possilble incoming messages 309 # o ack requested ? 310 # o signature requested ? 311 # o encryption requested ? 312 313 error_messages = Array.new 314 315 if !ebMS_message.is_ebMS_signal? then 316 if info_structure['info']['mc-ackRequested'] == 'always' and !ebMS_message.ack_requested? then 317 require 'pp' 318 pp info_structure['info'] 319 pp ebMS_message.to_s 320 error_messages << ( HefeWeizen::HefeWeizenLibrary::EBMSError.new "", "CPA says message must acknowledged but ebXML message does not include the Request for an Acknowledgment. This is a contradiction." ) 321 elsif info_structure['info']['mc-ackRequested'] == 'never' and ebMS_message.ack_requested? then 322 error_messages << ( HefeWeizen::HefeWeizenLibrary::EBMSError.new "", "CPA says message must not never be acknowledged but ebXML message does include the Request for an Acknowledgment. This is a conradiction." ) 323 end 324 end 325 326 # TODO 327 # Reliable Messaging 328 # o check duplicate elimination 329 # --> lookup message id 330 # fill validation_errors 331 332 # TODO 333 # Decrypt if encrypted $ 334 # --> needs to be done in the EBMSMesage constructor? so that the payloads can be decrypted? 335 # --> maybe if the payloads are encrypted the EBMSMessage constructor should not unpackage the payloads but 336 # have a special method for it and that method would be called now. 337 # fill validation_errors 338 339 # TODO 340 # Validate signature if signed 341 # fill validation_errors 342 343 @logger.debug "ebMS Message check not yet completely implemented." 344 if !error_messages.empty? then 345 msg = error_messages.join("\n") 346 @logger.warn msg 347 return false, nil, error_messages 348 end 349 end 350 return true, info_structure, [] 351 end 352 189 353 def has_identity? id 190 354 @parameters['identities'].each{ | identity_hash | branches/message-handling-refactor-branch/src/hefeweizen_library_directive.rb
r227 r229 11 11 class HefeWeizenDirective 12 12 13 attr_reader :file, :hash_value 13 attr_reader :file, :hash_value, :tags 14 14 15 15 def initialize config, file_path branches/message-handling-refactor-branch/src/hefeweizen_library_ebMS_message2.rb
r227 r229 40 40 # A plain message is one that has not been signed and not been 41 41 # encrypted. 42 def create_ plain_message directive, ebMS_message_info42 def create_ebXML_message_file directive, ebMS_message_info 43 43 party_ids = get_party_ids directive, ebMS_message_info 44 44 45 file_path = "#{@config['TEMP_FILE_DIR']}/ebXML_message.ebMS2__#{Time.now.to_f.to_s}" 46 45 47 # message id handling 46 48 message_id = directive.messageId.nil? ? create_message_id(ebMS_message_info['from']) : directive.messageId 47 ebXML_message_dir_path = "#{@message_store_directory}/#{message_id}"48 if FileTest.exists? ebXML_message_dir_path then49 @logger.debug "There is an already existing ebXML message with the message id #{message_id} for party #{@b2b_system_name}. Trying a new message id #{message_id}"50 message_id = create_message_id(ebMS_message_info['from'])51 ebXML_message_dir_path = "#{@message_store_directory}/#{message_id}"52 if FileTest.exists? ebXML_message_dir_path then53 @logger.warn "There is an already existing ebXML message with the message id #{message_id} for party #{@b2b_system_name}"54 # TODO55 # what to do if there is already an ebXML message with that id???56 return nil57 end58 end59 60 FileUtils.mkdir_p ebXML_message_dir_path61 62 # conversation id handling63 49 conversation_id = directive.conversationId.nil? ? create_conversation_id : directive.conversationId 64 conversation_id_directory = "#{@conversation_store_directory}/#{conversation_id}" 65 if !FileTest.exists? conversation_id_directory then 66 time = Time.now 67 FileUtils.mkdir conversation_id_directory 68 FileUtils.touch "#{conversation_id_directory}/created_at__#{time.to_f.to_s}__#{time.to_s}" 69 end 70 50 71 51 # creating the ebXML message 72 ebXML_message_file_name = "ebXML_message.ebMS2"73 complete_ebXML_message_file_path = "#{ebXML_message_dir_path}/#{ebXML_message_file_name}"74 time = Time.now75 52 success = TempEBMessage2.create_message( party_ids, directive, ebMS_message_info, 76 complete_ebXML_message_file_path, @config, message_id, 77 conversation_id) 78 53 file_path, @config, message_id, conversation_id) 54 79 55 if !success then 80 56 @logger.warn "Error creating ebXML message." 81 if FileTest.exists? ebXML_message_dir_path then82 FileUtils.rm _rf ebXML_message_dir_path57 if FileTest.exists? file_path then 58 FileUtils.rm file_path 83 59 end 84 60 return nil 85 61 end 86 87 # associating the message id with the conversation id (via file touch) 88 FileUtils.touch "#{conversation_id_directory}/ebXML_message__#{message_id}" 89 90 # create the metadata file (holds the ebXML message parameters or ebXML mesasge info structure) 91 ebXML_message_parameters_file_path = "ebXML_message_parameters.yml" 92 complete_ebXML_message_parameters_file_path = "#{ebXML_message_dir_path}/#{ebXML_message_parameters_file_path}" 93 success = create_ebXML_message_parameters_file complete_ebXML_message_parameters_file_path, ebMS_message_info 94 if !success then 95 @logger.warn "Error creating the ebXML message parameters file." 62 63 return { 64 'temp_ebXML_message_file_path' => file_path, 65 'ebXML_message_id' => message_id, 66 'ebXML_message_conversation_id' => conversation_id} 67 68 end 69 70 def create_ebXML_message_object_from_string string 71 if string.nil? or string.empty? then 72 @logger.warn "String is nil or empty." 96 73 return nil 97 74 end 98 99 # do message magic 100 # start to add metadata, states etc. 101 FileUtils.touch "#{ebXML_message_dir_path}/created_at__#{time.to_f.to_s}__#{time.to_s}" 102 103 result = {'ebXML_message_dir_path' => ebXML_message_dir_path, 104 'complete_ebXML_message_file_path' => complete_ebXML_message_file_path, 105 'ebXML_message_file_name' => ebXML_message_file_name, 106 'ebXML_message_parameters_file_name' => ebXML_message_parameters_file_path, 107 'complete_ebXML_message_parameters_file_path' => complete_ebXML_message_parameters_file_path, 108 'message_id' => message_id, 109 'conversation_id' => conversation_id} 110 111 return result 112 end 113 75 begin 76 ebXML_message_object = TempEBMessage2.new @config, string, "string" 77 return ebXML_message_object 78 rescue Exception => e 79 @logger.warn "Error creating ebXML message from string. Error: #{e.to_s}, #{e.backtrace}" 80 return nil 81 end 82 83 end 84 85 def create_ebXML_message_object_from_file ebXML_message_file_path 86 if ebXML_message_file_path.nil? then 87 @logger.warn "There is no ebXML message file path." 88 return nil 89 end 90 begin 91 ebXML_message_object = TempEBMessage2.new @config, ebXML_message_file_path, "file" 92 return ebXML_message_object 93 rescue Exception => e 94 @logger.warn "Error creating ebXML message from file. Error: #{e.to_s}, #{e.backtrace}" 95 return nil 96 end 97 98 end 99 100 # This method updates the message store with the information of a new ebXML message 101 # o this includes to add the ebXML message 102 # o this includes to add the conversation id directory 103 # o this includes to associate the ebXML message with the conversation id directory 104 # TODO 105 # o this includes to set the acknowledgment, error references. 106 # --> if this ebXML message is an error message than we link to the orignal ebXML message. 107 # --> if this ebXML message is an acknowledgment than we link to the orignal ebXML message. 108 # --> the orignal ebXML message gets a link to this ebXML message 109 def add_ebXML_message_file_to_message_store b2b_system_name, metadata_about_ebXML_message 110 if metadata_about_ebXML_message.nil? then 111 @logger.warn "Unable to add ebXML message to message store becuase message reference is empty" 112 return nil 113 end 114 115 source = metadata_about_ebXML_message['temp_ebXML_message_file_path'] 116 if !FileTest.exists? source and !FileTest.owned? source then 117 @logger.warn "The ebXML message at '#{source}' is not readable or not moveable." 118 return nil 119 end 120 121 # first check if such an ebXML message is already stored (check by message_id) 122 ebXML_message_id = metadata_about_ebXML_message['ebXML_message_id'] 123 dir = "#{@config['MESSAGE_DIR']}/#{b2b_system_name}/#{ebXML_message_id}" 124 if FileTest.exists? dir then 125 msg = "There is a problem. There is already an ebXML message with the message id '#{ebXML_message_id}' in " + 126 " the message store. Checked in directory #{dir}." 127 @logger.warn msg 128 return nil 129 end 130 # 1. creating the ebXML mesage id directory. 131 # 2. move the incoming ebXML message right there 132 time = Time.now 133 FileUtils.mkdir_p dir 134 FileUtils.touch "#{dir}/created_at__#{time.to_s}" 135 complete_ebXML_message_file_path = "#{dir}/ebXML_message.ebMS2" 136 FileUtils.mv metadata_about_ebXML_message['temp_ebXML_message_file_path'], complete_ebXML_message_file_path 137 138 # 1. create ebXML message conversation id directory (if not there already). 139 # 2. add ebXML message id to conversation id 140 ebXML_message_conversation_id = metadata_about_ebXML_message['ebXML_message_conversation_id'] 141 dir2 = "#{@config['CONVERSATION_DIR']}/#{b2b_system_name}/#{ebXML_message_conversation_id}" 142 if ! FileTest.exists? dir2 then 143 FileUtils.mkdir dir2 144 FileUtils.touch "#{dir2}/created_at__#{time.to_s}" 145 end 146 temp_ebXML_message_file_name = "ebXML_message_id__#{ebXML_message_id}" 147 FileUtils.touch "#{dir2}/#{temp_ebXML_message_file_name}" 148 149 return dir 150 151 end 152 153 def add_ebXML_message_info_file_to_message_store system_name, directory, ebMS_info_file_path 154 if system_name.nil? or directory.nil? or ebMS_info_file_path.nil? then 155 @logger.warn "System name, directory, or ebMS info file path not given." 156 return nil 157 end 158 if !FileTest.exists? ebMS_info_file_path or !FileTest.owned? ebMS_info_file_path or !FileTest.directory? directory or 159 !FileTest.writable? directory then 160 @logger.warn "Error (non existent or non readable) with directory '#{directory}' or file '#{ebMS_info_file_path}'." 161 return nil 162 end 163 target = "#{directory}/ebXML_message_parameters.yml" 164 FileUtils.mv ebMS_info_file_path, target 165 return true 166 end 167 114 168 private 115 116 def create_ebXML_message_parameters_file file_path, ebMS_message_info117 file = File.new(file_path, "w")118 # what is multipart used for?119 # ebMS_message_info['is_multipart'] = is_multipart.to_s120 YAML.dump ebMS_message_info, file121 file.close122 return true123 end124 125 169 126 170 ####################################### … … 179 223 end 180 224 225 end # ebXML Message Manager class 226 227 228 class EBMSError 229 230 attr_reader :severity, :description, :code 231 232 def initialize severity, description, code = "FUCKER CODE" 233 @severity = severity.empty? ? "Error" : severity 234 @description = description 235 @code = code 236 end 237 238 def to_s 239 "Error code '#{@code}' with severity '#{@severity}'. Error description: #{description}." 240 end 181 241 end 182 242 243 183 244 class TempEBMessage2 184 245 246 attr_reader :message, :action, :service, :cpa_id, :message_timestamp, :from_name, :from_type, :to_name, :to_type 247 attr_reader :message_id, :conversation_id 248 attr_reader :from_role, :to_role 249 attr_reader :references, :payloads 250 attr_reader :errors 251 attr_reader :raw_message_file_path 185 252 186 253 # TODO … … 198 265 end 199 266 200 201 267 # This method creates an ebXML Message based on directives and ebMS message infos. 202 268 def TempEBMessage2.create_message party_ids, directive, ebMS_message_info, complete_ebXML_message_file_path, … … 207 273 208 274 ebXML_message = File.new "#{complete_ebXML_message_file_path}", "w" 275 ebXML_message.sync = true 209 276 210 277 if ebMS_message_info['service'] == 'urn:oasis:names:tc:ebxml-msg:service' and ebMS_message_info['action'] == 'Ping' then … … 301 368 <eb:MessageData> 302 369 <eb:MessageId>#{message_id}</eb:MessageId> 303 <eb:Timestamp>#{ EBMessage2.create_timestamp}</eb:Timestamp>370 <eb:Timestamp>#{create_timestamp}</eb:Timestamp> 304 371 </eb:MessageData>#{duplicate_elimination} 305 372 </eb:MessageHeader>#{ack_requested} … … 347 414 # Possibly everything goes through memory. 348 415 # my_command = "cat #{payload_path} >> #{file_path}" 349 416
