Ejemplo n.º 1
0
def test_is_feature_flag(code, is_active, lookup, expected):
    """Tests if is_feature_flag returns correct state of feature flag."""
    if code != '':
        FeatureFlagFactory(code=code, is_active=is_active)

    result = is_feature_flag_active(lookup)
    assert result is expected
Ejemplo n.º 2
0
 def _enrich_data(self, data):
     """
     Get the marketing consent from the consent service
     """
     if is_feature_flag_active(GET_CONSENT_FROM_CONSENT_SERVICE):
         emails = [item['email'] for item in data]
         consent_lookups = consent.get_many(emails)
         for item in data:
             item['accepts_dit_email_marketing'] = consent_lookups.get(
                 item['email'], False)
     return data
Ejemplo n.º 3
0
def _get_desired_stage_order(desired_stage, next_stage):
    if not next_stage:
        return desired_stage.order

    is_streamlined_flow_active = is_feature_flag_active(
        FEATURE_FLAG_STREAMLINED_FLOW)

    if is_streamlined_flow_active and str(
            desired_stage.id) == Stage.prospect.value.id:
        return desired_stage.order + 200.0

    return desired_stage.order + 100.0
Ejemplo n.º 4
0
    def changelist_view(self, request, extra_context=None):
        """
        The changelist view.

        Overridden to add the add adviser from SSO feature flag to the template context.

        TODO: Remove this once the feature flag has been removed.
        """
        combined_extra_context = {
            'show_add_from_sso':
            is_feature_flag_active(ADMIN_ADD_ADVISER_FROM_SSO_FEATURE_FLAG),
            **(extra_context or {}),
        }
        return super().changelist_view(request, combined_extra_context)
Ejemplo n.º 5
0
def update_contact_consent(email_address, accepts_dit_email_marketing, modified_at=None):
    """
    Archive inactive companies.
    """
    if not is_feature_flag_active(UPDATE_CONSENT_SERVICE_FEATURE_FLAG):
        logger.info(
            f'Feature flag "{UPDATE_CONSENT_SERVICE_FEATURE_FLAG}" is not active, exiting.',
        )
        return
    consent.update_consent(
        email_address,
        accepts_dit_email_marketing,
        modified_at=modified_at,
    )
Ejemplo n.º 6
0
    def complete(self):
        """Complete a proposition."""
        if not is_feature_flag_active(FEATURE_FLAG_PROPOSITION_DOCUMENT):
            # if proposition documents are not enabled, "details" field is mandatory
            if self.validated_data['details'] == '':
                raise ValidationError({
                    'details': ['This field may not be blank.'],
                })

        self.instance.complete(
            by=self.context['current_user'],
            details=self.validated_data['details'],
        )
        return self.instance
Ejemplo n.º 7
0
def notify_new_dnb_investigation(company):
    """
    Notify DNB of a new company investigation.
    """
    if not is_feature_flag_active(NOTIFY_DNB_INVESTIGATION_FEATURE_FLAG):
        return
    investigation_context = get_dnb_investigation_context(company)
    recipients = settings.DNB_INVESTIGATION_NOTIFICATION_RECIPIENTS
    for email_address in recipients:
        notify_by_email(
            email_address,
            Template.request_new_business_record.value,
            investigation_context,
            notify_service_name=NotifyServiceName.dnb_investigation,
        )
Ejemplo n.º 8
0
    def complete(self, by, details):
        """
        Complete a proposition

        :param by: the adviser who marked the proposition as complete
        :param details: details of completion
        :raises ValidationError: when trying to complete proposition without uploaded documents
        :raises APIConflictException: when proposition status is not ongoing
        """
        if is_feature_flag_active(FEATURE_FLAG_PROPOSITION_DOCUMENT):
            if self.documents.filter(document__status=UPLOAD_STATUSES.virus_scanned).count() == 0:
                raise ValidationError({
                    'non_field_errors': ['Proposition has no documents uploaded.'],
                })
        self._change_status(PropositionStatus.completed, by, details)
Ejemplo n.º 9
0
def automatic_company_archive(self, limit=1000, simulate=True):
    """
    Archive inactive companies.
    """
    if not is_feature_flag_active(AUTOMATIC_COMPANY_ARCHIVE_FEATURE_FLAG):
        logger.info(
            f'Feature flag "{AUTOMATIC_COMPANY_ARCHIVE_FEATURE_FLAG}" is not active, exiting.',
        )
        return

    with advisory_lock('automatic_company_archive', wait=False) as acquired:

        if not acquired:
            logger.info('Another instance of this task is already running.')
            return

        _automatic_company_archive(limit, simulate)
Ejemplo n.º 10
0
    def _send_email(self, **data):
        """Send email in a separate thread."""
        # override recipient if needed
        if settings.OMIS_NOTIFICATION_OVERRIDE_RECIPIENT_EMAIL:
            data[
                'email_address'] = settings.OMIS_NOTIFICATION_OVERRIDE_RECIPIENT_EMAIL

        use_notification_app = is_feature_flag_active(
            OMIS_USE_NOTIFICATION_APP_FEATURE_FLAG_NAME)
        if use_notification_app:
            notify_by_email(
                data['email_address'],
                data['template_id'],
                data.get('personalisation'),
                NotifyServiceName.omis,
            )
        else:
            submit_to_thread_pool(send_email, self.client, **data)
Ejemplo n.º 11
0
def process_mailbox_emails():
    """
    Process new emails for S3 mailboxes.
    """
    # NOTE: This is a long-lived feature flag which allows us to quickly switch off email
    # ingestion in case of any problems with third party (SMTP) services or security issues
    if not is_feature_flag_active(MAILBOX_INGESTION_FEATURE_FLAG_NAME):
        logger.info(
            f'Feature flag "{MAILBOX_INGESTION_FEATURE_FLAG_NAME}" is not active, '
            'exiting.', )
        return
    # Acquire a processing lock for the duration of the current DB session -
    # this will ensure that multiple ingestion workers do not run at the same
    # time and therefore prevent the chance of messages being processed more
    # than once
    with advisory_lock('process_mailbox_emails', wait=False) as acquired:
        if not acquired:
            logger.info('Emails are already being processed by another worker')
            return
        emails.process_ingestion_emails()
Ejemplo n.º 12
0
def automatic_company_archive(self, limit=1000, simulate=True):
    """
    Archive inactive companies.
    """
    if not is_feature_flag_active(AUTOMATIC_COMPANY_ARCHIVE_FEATURE_FLAG):
        logger.info(
            f'Feature flag "{AUTOMATIC_COMPANY_ARCHIVE_FEATURE_FLAG}" is not active, exiting.',
        )
        return

    with advisory_lock('automatic_company_archive', wait=False) as acquired:

        if not acquired:
            logger.info('Another instance of this task is already running.')
            return

        archive_count = _automatic_company_archive(limit, simulate)
        realtime_message = f'{self.name} archived: {archive_count}'
        if simulate:
            realtime_message = f'[SIMULATE] {realtime_message}'
        send_realtime_message(realtime_message)
Ejemplo n.º 13
0
def get_company_updates(self, last_updated_after=None, fields_to_update=None):
    """
    Gets the lastest updates for D&B companies from dnb-service.

    The `dnb-service` exposes these updates as a cursor-paginated list. This
    task goes through the pages and spawns tasks that update the records in
    Data Hub.
    """
    # TODO: remove this feature flag after a reasonable period after going live
    # with unlimited company updates
    if not is_feature_flag_active(FEATURE_FLAG_DNB_COMPANY_UPDATES):
        logger.info(
            f'Feature flag "{FEATURE_FLAG_DNB_COMPANY_UPDATES}" is not active, exiting.',
        )
        return

    with advisory_lock('get_company_updates', wait=False) as acquired:

        if not acquired:
            logger.info('Another instance of this task is already running.')
            return

        _get_company_updates(self, last_updated_after, fields_to_update)
Ejemplo n.º 14
0
def ingest_emails():
    """
    Ingest and process new emails for all mailboxes in the application - i.e.
    those in the MAILBOXES django setting.
    """
    # NOTE: This is a long-lived feature flag which allows us to quickly switch off email
    # ingestion in case of any problems with third party (SMTP) services or security issues
    if not is_feature_flag_active(
            INTERACTION_EMAIL_INGESTION_FEATURE_FLAG_NAME):
        logger.info(
            f'Feature flag "{INTERACTION_EMAIL_INGESTION_FEATURE_FLAG_NAME}" is not active, '
            'exiting.', )
        return
    # Acquire a processing lock for the duration of the current DB session -
    # this will ensure that multiple ingestion workers do not run at the same
    # time and therefore prevent the chance of messages being processed more
    # than once
    with advisory_lock('ingest_emails', wait=False) as acquired:
        if not acquired:
            logger.info('Emails are already being ingested by another worker')
            return
        for mailbox in mailbox_handler.get_all_mailboxes():
            mailbox.process_new_mail()
Ejemplo n.º 15
0
def notify_meeting_ingest_success(adviser, interaction, recipients):
    """
    Notify an adviser that a meeting ingest has succeeeded - including a link
    to the interaction and intended recipients.
    """
    domain_label = get_domain_label(adviser.get_email_domain())
    statsd.incr(f'celery.calendar-invite-ingest.success.{domain_label}')
    if not is_feature_flag_active(
            INTERACTION_EMAIL_NOTIFICATION_FEATURE_FLAG_NAME):
        logger.info(
            f'Feature flag "{INTERACTION_EMAIL_NOTIFICATION_FEATURE_FLAG_NAME}" is not active, '
            'exiting.', )
        return

    flat_recipients = ', '.join(recipients)
    notify_adviser_by_email(
        adviser,
        Template.meeting_ingest_success.value,
        context={
            'interaction_url': interaction.get_absolute_url(),
            'recipients': flat_recipients,
            'support_team_email': settings.DATAHUB_SUPPORT_EMAIL_ADDRESS,
        },
    )
Ejemplo n.º 16
0
def notify_meeting_ingest_failure(adviser, errors, recipients):
    """
    Notify an adviser that a meeting ingest has failed - including error
    details and intended recipients.
    """
    domain_label = get_domain_label(adviser.get_email_domain())
    statsd.incr(f'celery.calendar-invite-ingest.failure.{domain_label}')
    if not is_feature_flag_active(
            INTERACTION_EMAIL_NOTIFICATION_FEATURE_FLAG_NAME):
        logger.info(
            f'Feature flag "{INTERACTION_EMAIL_NOTIFICATION_FEATURE_FLAG_NAME}" is not active, '
            'exiting.', )
        return

    flat_recipients = ', '.join(recipients)
    notify_adviser_by_email(
        adviser,
        Template.meeting_ingest_failure.value,
        context={
            'errors': errors,
            'recipients': flat_recipients,
            'support_team_email': settings.DATAHUB_SUPPORT_EMAIL_ADDRESS,
        },
    )
Ejemplo n.º 17
0
 def __init__(self):
     """Checking feature flags that alter validation mapping."""
     self.is_streamlined_flow = is_feature_flag_active(
         FEATURE_FLAG_STREAMLINED_FLOW)
Ejemplo n.º 18
0
 def __call__(self, _) -> bool:
     """
     Returns True if the feature flag is active.
     """
     return is_feature_flag_active(self.feature_flag)