def end_auction(self):
        request_id = generate_request_id()
        LOGGER.info('---------------- End auction ----------------',
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_AUCTION
                    })

        LOGGER.debug("Stop server", extra={"JOURNAL_REQUEST_ID": request_id})
        if self.context.get('server'):
            self.context['server'].stop()

        delete_mapping(self.context['worker_defaults'],
                       self.context['auction_doc_id'])
        LOGGER.debug("Clear mapping", extra={"JOURNAL_REQUEST_ID": request_id})

        stage = {
            'start': datetime.now(TIMEZONE).isoformat(),
            'type': PREANNOUNCEMENT,
        }
        with update_auction_document(self.context,
                                     self.database) as auction_document:
            auction_document["stages"].append(stage)
            auction_document["current_stage"] = len(
                auction_document["stages"]) - 1

        auction_protocol = approve_auction_protocol_info_on_announcement(
            self.context['auction_document'], self.context['auction_protocol'])
        self.context['auction_protocol'] = auction_protocol
        LOGGER.info('Audit data: \n {}'.format(
            yaml_dump(self.context['auction_protocol'])),
                    extra={"JOURNAL_REQUEST_ID": request_id})
        LOGGER.info(self.context['auction_protocol'])

        result = self.datasource.update_source_object(
            self.context['auction_data'], self.context['auction_document'],
            self.context['auction_protocol'])
        if result and isinstance(result, dict):
            self.context['auction_document'] = result

        auction_end = datetime.now(TIMEZONE)
        stage = prepare_end_stage(auction_end)
        with update_auction_document(self.context,
                                     self.database) as auction_document:
            auction_document["stages"].append(stage)
            auction_document["current_stage"] = len(
                auction_document["stages"]) - 1
            auction_document['endDate'] = auction_end.isoformat()

        self.context['end_auction_event'].set()
Пример #2
0
 def cancel_auction(self):
     self.context['auction_document'] = self.database.get_auction_document(
         self.context['auction_doc_id'])
     if self.context['auction_document']:
         with utils.update_auction_document(
                 self.context, self.database) as auction_document:
             LOGGER.info("Auction {} canceled".format(
                 self.context['auction_doc_id']),
                         extra={
                             'MESSAGE_ID':
                             AUCTION_WORKER_SERVICE_AUCTION_CANCELED
                         })
             auction_document["current_stage"] = -100
             auction_document["endDate"] = datetime.now(
                 TIMEZONE).isoformat()
             LOGGER.info("Change auction {} status to 'canceled'".format(
                 self.context['auction_doc_id']),
                         extra={
                             'MESSAGE_ID':
                             AUCTION_WORKER_SERVICE_AUCTION_STATUS_CANCELED
                         })
     else:
         LOGGER.info(
             "Auction {} not found".format(self.context['auction_doc_id']),
             extra={'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_NOT_FOUND})
 def add_bid(self, current_stage, bid):
     LOGGER.info(
         '------------------ Adding bid ------------------',
     )
     # Updating auction document with bid data
     with utils.update_auction_document(self.context, self.database) as auction_document:
         try:
             bid['bidder_name'] = self.context['bids_mapping'].get(bid['bidder_id'], False)
             result = utils.prepare_results_stage(**bid)
             auction_document['stages'][current_stage].update(result)
             results = auction_document['results']
             bid_index = next((i for i, res in enumerate(results)
                               if res['bidder_id'] == bid['bidder_id']), None)
             if bid_index is not None:
                 results[bid_index] = result
             else:
                 results.append(result)
             auction_document['results'] = sorting_by_amount(results)
         except Exception as e:
             LOGGER.fatal(
                 "Exception during adding bid. "
                 "Error: {}".format(e)
             )
             return e
     self.end_bid_stage(bid)
     return True
Пример #4
0
    def post_announce(self):
        self.context['auction_document'] = self.database.get_auction_document(
            self.context['auction_doc_id'])
        auction = self.datasource.get_data(with_credentials=True)

        bids_information = utils.get_bids(auction)
        with utils.update_auction_document(self.context,
                                           self.database) as auction_document:
            utils.open_bidders_name(auction_document, bids_information)
    def end_bid_stage(self, bid):
        request_id = generate_request_id()
        LOGGER.info(
            '---------------- End Bids Stage ----------------',
            extra={"JOURNAL_REQUEST_ID": request_id,
                   "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_BID_STAGE}
        )

        # Cleaning up preplanned jobs
        SCHEDULER.remove_all_jobs()

        # Update auction protocol
        auction_protocol = approve_auction_protocol_info_on_bids_stage(
            self.context['auction_document'], self.context['auction_protocol']
        )
        self.context['auction_protocol'] = auction_protocol

        with utils.update_auction_document(self.context, self.database) as auction_document:
            # Creating new stages
            bid_document = {
                'value': {'amount': bid['amount']},
                'minimalStep': auction_document['minimalStep']
            }

            pause, main_round = utils.prepare_auction_stages(
                utils.convert_datetime(bid['time']),
                bid_document,
                self.context.get('deadline'),
                fast_forward=self.context['worker_defaults'].get('sandbox_mode', False)
            )

            auction_document['stages'].append(pause)
            if main_round:
                auction_document['stages'].append(main_round)

            # Updating current stage
            auction_document["current_stage"] += 1

        LOGGER.info('---------------- Start stage {0} ----------------'.format(
            self.context['auction_document']["current_stage"]),
            extra={"JOURNAL_REQUEST_ID": request_id,
                   "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE}
        )

        # Adding jobs to scheduler
        deadline = self.context.get('deadline')

        if main_round:
            round_start_date = utils.convert_datetime(main_round['start'])
            round_end_date = get_round_ending_time(
                round_start_date, ROUND_DURATION, deadline
            )

            self.job_service.add_pause_job(round_start_date)
            self.job_service.add_ending_main_round_job(round_end_date)
        else:
            self.job_service.add_ending_main_round_job(deadline)
Пример #6
0
 def add_bid(self, current_stage, bid):
     LOGGER.info('------------------ Adding bid ------------------', )
     # Updating auction document with bid data
     with utils.update_auction_document(self.context,
                                        self.database) as auction_document:
         bid['bidder_name'] = self.context['bids_mapping'].get(
             bid['bidder_id'], False)
         self.context['_bids_data'][bid['bidder_id']].append(deepcopy(bid))
         result = utils.prepare_results_stage(**bid)
         auction_document['stages'][current_stage].update(result)
         auction_document['results'].append(result)
     self.end_bid_stage(bid)
Пример #7
0
    def switch_to_next_stage(self):
        request_id = generate_request_id()

        with lock_server(self.context['server_actions']):
            with update_auction_document(self.context,
                                         self.database) as auction_document:
                auction_document["current_stage"] += 1

        LOGGER.info('---------------- Start stage {0} ----------------'.format(
            self.context['auction_document']["current_stage"]),
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE
                    })
Пример #8
0
    def end_bid_stage(self, bid):
        request_id = generate_request_id()
        LOGGER.info('---------------- End Bids Stage ----------------',
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_BID_STAGE
                    })

        # Cleaning up preplanned jobs
        SCHEDULER.remove_all_jobs()

        with utils.update_auction_document(self.context,
                                           self.database) as auction_document:
            # Creating new stages
            bid_document = {
                'value': {
                    'amount': bid['amount']
                },
                'minimalStep': auction_document['minimalStep']
            }

            pause, main_round = utils.prepare_auction_stages(
                utils.convert_datetime(bid['time']), bid_document)

            auction_document['stages'].append(pause)
            if main_round:
                auction_document['stages'].append(main_round)

            # Updating current stage
            auction_document["current_stage"] += 1

        LOGGER.info('---------------- Start stage {0} ----------------'.format(
            self.context['auction_document']["current_stage"]),
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_START_NEXT_STAGE
                    })

        # Adding jobs to scheduler
        deadline = set_specific_hour(datetime.now(TIMEZONE), DEADLINE_HOUR)

        if main_round:
            round_start_date = utils.convert_datetime(main_round['start'])
            round_end_date = get_round_ending_time(round_start_date,
                                                   ROUND_DURATION, deadline)

            self.job_service.add_pause_job(round_start_date)
            self.job_service.add_ending_main_round_job(round_end_date)
        else:
            self.job_service.add_ending_main_round_job(deadline)
Пример #9
0
    def schedule_auction(self):
        self.context['auction_document'] = self.database.get_auction_document(
            self.context['auction_doc_id'])
        with utils.update_auction_document(self.context,
                                           self.database) as auction_document:
            if self.debug:
                LOGGER.info("Get _auction_data from auction_document")
                self._auction_data = auction_document.get(
                    'test_auction_data', {})
            self.synchronize_auction_info()
            self.context['auction_data'] = deepcopy(self._auction_data)
            self.context['bidders_data'] = deepcopy(self.bidders_data)
            self.context['bids_mapping'] = deepcopy(self.bids_mapping)
            self.auction_protocol = utils.prepare_auction_protocol(
                self.context)
            self.context['auction_protocol'] = deepcopy(self.auction_protocol)

        if self.context['auction_document'].get(
                'submissionMethodDetails') == 'quick':
            utils.set_relative_deadline(self.context, self.startDate,
                                        SANDBOX_AUCTION_DURATION)
        else:
            utils.set_absolute_deadline(self.context, self.startDate)

        # Add job that starts auction server
        SCHEDULER.add_job(
            self.start_auction,
            'date',
            run_date=utils.convert_datetime(
                self.context['auction_document']['stages'][0]['start']),
            name="Start of Auction",
            id="auction:start")

        # Add job that switch current_stage to round stage
        start = utils.convert_datetime(
            self.context['auction_document']['stages'][1]['start'])
        self.job_service.add_pause_job(start)

        # Add job that end auction
        start = utils.convert_datetime(
            self.context['auction_document']['stages'][1]
            ['start']) + timedelta(seconds=ROUND_DURATION)
        self.job_service.add_ending_main_round_job(start)

        self.server = run_server(
            self,
            None,  # TODO: add mapping expire
            LOGGER)
        self.context['server'] = self.server
Пример #10
0
 def reschedule_auction(self):
     self.context['auction_document'] = self.database.get_auction_document(
         self.context['auction_doc_id'])
     if self.context['auction_document']:
         with utils.update_auction_document(
                 self.context, self.database) as auction_document:
             LOGGER.info(
                 "Auction {} has not started and will be rescheduled".
                 format(self.context['auction_doc_id']),
                 extra={
                     'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_RESCHEDULE
                 })
             auction_document["current_stage"] = -101
     else:
         LOGGER.info(
             "Auction {} not found".format(self.context['auction_doc_id']),
             extra={'MESSAGE_ID': AUCTION_WORKER_SERVICE_AUCTION_NOT_FOUND})
Пример #11
0
    def start_auction(self):
        request_id = generate_request_id()
        self.auction_protocol['timeline']['auction_start'][
            'time'] = datetime.now(TIMEZONE).isoformat()

        LOGGER.info('---------------- Start auction  ----------------',
                    extra={
                        "JOURNAL_REQUEST_ID": request_id,
                        "MESSAGE_ID": AUCTION_WORKER_SERVICE_END_FIRST_PAUSE
                    })
        self.synchronize_auction_info()
        with utils.lock_server(
                self.context['server_actions']), utils.update_auction_document(
                    self.context, self.database) as auction_document:
            self._prepare_initial_bids(auction_document)
            auction_document["current_stage"] = 0
            LOGGER.info("Switched current stage to {}".format(
                auction_document['current_stage']))
Пример #12
0
    def schedule_auction(self):
        self.context['auction_document'] = self.database.get_auction_document(
            self.context['auction_doc_id'])
        with utils.update_auction_document(self.context,
                                           self.database) as auction_document:
            if self.debug:
                LOGGER.info("Get _auction_data from auction_document")
                self._auction_data = auction_document.get(
                    'test_auction_data', {})
            self.synchronize_auction_info()
            self.audit = utils.prepare_audit()
            self.context['audit'] = deepcopy(self.audit)
            self.context['auction_data'] = deepcopy(self._auction_data)
            self.context['bidders_data'] = deepcopy(self.bidders_data)
            self.context['bids_mapping'] = deepcopy(self.bids_mapping)

        # Add job that starts auction server
        SCHEDULER.add_job(
            self.start_auction,
            'date',
            run_date=utils.convert_datetime(
                self.context['auction_document']['stages'][0]['start']),
            name="Start of Auction",
            id="auction:start")

        # Add job that switch current_stage to round stage
        start = utils.convert_datetime(
            self.context['auction_document']['stages'][1]['start'])
        self.job_service.add_pause_job(start)

        # Add job that end auction
        start = utils.convert_datetime(
            self.context['auction_document']['stages'][1]
            ['start']) + timedelta(seconds=ROUND_DURATION)
        self.job_service.add_ending_main_round_job(start)

        self.server = run_server(
            self,
            None,  # TODO: add mapping expire
            LOGGER)
        self.context['server'] = self.server