<commit_before>from functools import wraps
from django.utils import timezone
from rest_framework import decorators, exceptions, response, status

from nodeconductor.structure import views as structure_views

from . import models, serializers
from .backend import OracleBackendError


def track_exceptions(view_fn):
    @wraps(view_fn)
    def wrapped(self, request, resource, *args, **kwargs):
        try:
            return view_fn(self, request, resource, *args, **kwargs)
        except OracleBackendError as e:
            resource.error_message = unicode(e)
            resource.set_erred()
            resource.save(update_fields=['state', 'error_message'])
            raise exceptions.APIException(e)
    return wrapped


class OracleServiceViewSet(structure_views.BaseServiceViewSet):
    queryset = models.OracleService.objects.all()
    serializer_class = serializers.ServiceSerializer


class OracleServiceProjectLinkViewSet(structure_views.BaseServiceProjectLinkViewSet):
    queryset = models.OracleServiceProjectLink.objects.all()
    serializer_class = serializers.ServiceProjectLinkSerializer


class DeploymentViewSet(structure_views.BaseResourceViewSet):
    queryset = models.Deployment.objects.all()
    serializer_class = serializers.DeploymentSerializer

    def get_serializer_class(self):
        if self.action == 'resize':
            return serializers.DeploymentResizeSerializer
        return super(DeploymentViewSet, self).get_serializer_class()

    def perform_provision(self, serializer):
        resource = serializer.save()
        backend = resource.get_backend()
        backend.provision(
            resource, self.request, ssh_key=serializer.validated_data.get('ssh_public_key'))

        resource.begin_provisioning()
        resource.save(update_fields=['state'])

    @decorators.detail_route(methods=['post'])
    @structure_views.safe_operation(valid_state=models.Deployment.States.PROVISIONING)
    def provision(self, request, resource, uuid=None):
        """ Complete provisioning. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/provision/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token <PASSWORD>
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='TST12DB'"
                }
        """<commit_msg>Handle exceptions on provisioning<commit_after>from functools import wraps
from django.utils import timezone
from rest_framework import decorators, exceptions, response, status

from nodeconductor.structure import views as structure_views

from . import models, serializers
from .backend import OracleBackendError


def track_exceptions(view_fn):
    @wraps(view_fn)
    def wrapped(self, request, resource, *args, **kwargs):
        try:
            return view_fn(self, request, resource, *args, **kwargs)
        except OracleBackendError as e:
            resource.error_message = unicode(e)
            resource.set_erred()
            resource.save(update_fields=['state', 'error_message'])
            raise exceptions.APIException(e)
    return wrapped


class OracleServiceViewSet(structure_views.BaseServiceViewSet):
    queryset = models.OracleService.objects.all()
    serializer_class = serializers.ServiceSerializer


class OracleServiceProjectLinkViewSet(structure_views.BaseServiceProjectLinkViewSet):
    queryset = models.OracleServiceProjectLink.objects.all()
    serializer_class = serializers.ServiceProjectLinkSerializer


class DeploymentViewSet(structure_views.BaseResourceViewSet):
    queryset = models.Deployment.objects.all()
    serializer_class = serializers.DeploymentSerializer

    def get_serializer_class(self):
        if self.action == 'resize':
            return serializers.DeploymentResizeSerializer
        return super(DeploymentViewSet, self).get_serializer_class()

    def perform_provision(self, serializer):
        resource = serializer.save()
        backend = resource.get_backend()

        try:
            backend.provision(
                resource, self.request, ssh_key=serializer.validated_data.get('ssh_public_key'))
        except OracleBackendError as e:
            resource.error_message = unicode(e)
            resource.set_erred()
            resource.save(update_fields=['state', 'error_message'])
            raise

        resource.begin_provisioning()
        resource.save(update_fields=['state'])

    @decorators.detail_route(methods=['post'])
    @structure_views.safe_operation(valid_state=models.Deployment.States.PROVISIONING)
    def provision(self, request, resource, uuid=None):
        """ Complete provisioning. Example:

            .. code-block:: http

                POST /api/oracle-deployments/a04a26e46def4724a0841abcb81926ac/provision/ HTTP/1.1
                Content-Type: application/json
                Accept: application/json
                Authorization: Token <PASSWORD>
                Host: example.com

                {
                    "report": "ORACONF=TST12DB\n\nDBTYPE=single\nDBNAME='TST12DB'"
                }
        """
{'fraction_non_alphanumeric': 0.08688995215311004, 'fraction_numerical': 0.009569377990430622, 'mean_word_length': 3.1279620853080567, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3592777', 'n_tokens_mistral': 1457, 'n_tokens_neox': 1383, 'n_words': 264}