コード例 #1
0
ファイル: sqlalchemy.py プロジェクト: ISCAS-VDI/gnocchi-base
    def create_resource(self,
                        resource_type,
                        id,
                        created_by_user_id,
                        created_by_project_id,
                        user_id=None,
                        project_id=None,
                        started_at=None,
                        ended_at=None,
                        metrics=None,
                        **kwargs):
        if (started_at is not None and ended_at is not None
                and started_at > ended_at):
            raise ValueError("Start timestamp cannot be after end timestamp")
        with self.facade.writer() as session:
            resource_cls = self._resource_type_to_classes(
                session, resource_type)['resource']
            r = resource_cls(id=id,
                             type=resource_type,
                             created_by_user_id=created_by_user_id,
                             created_by_project_id=created_by_project_id,
                             user_id=user_id,
                             project_id=project_id,
                             started_at=started_at,
                             ended_at=ended_at,
                             **kwargs)
            session.add(r)
            try:
                session.flush()
            except exception.DBDuplicateEntry:
                raise indexer.ResourceAlreadyExists(id)
            except exception.DBReferenceError as ex:
                raise indexer.ResourceValueError(r.type, ex.key,
                                                 getattr(r, ex.key))
            if metrics is not None:
                self._set_metrics_for_resource(session, r, metrics)

            # NOTE(jd) Force load of metrics :)
            r.metrics

            return r
コード例 #2
0
    def update_resource(self,
                        resource_type,
                        resource_id,
                        ended_at=_marker,
                        metrics=_marker,
                        append_metrics=False,
                        create_revision=True,
                        **kwargs):
        resource_cls = self._resource_type_to_class(resource_type)
        resource_history_cls = self._resource_type_to_class(
            resource_type, "history")
        with self.facade.writer() as session:
            try:
                # NOTE(sileht): We use FOR UPDATE that is not galera friendly,
                # but they are no other way to cleanly patch a resource and
                # store the history that safe when two concurrent calls are
                # done.
                q = session.query(resource_cls).filter(
                    resource_cls.id == resource_id).with_for_update()

                r = q.first()
                if r is None:
                    raise indexer.NoSuchResource(resource_id)

                if create_revision:
                    # Build history
                    rh = resource_history_cls()
                    for col in sqlalchemy.inspect(resource_cls).columns:
                        setattr(rh, col.name, getattr(r, col.name))
                    now = utils.utcnow()
                    rh.revision_end = now
                    session.add(rh)
                    r.revision_start = now

                # Update the resource
                if ended_at is not _marker:
                    # NOTE(jd) MySQL does not honor checks. I hate it.
                    engine = session.connection()
                    if engine.dialect.name == "mysql":
                        if r.started_at is not None and ended_at is not None:
                            if r.started_at > ended_at:
                                raise indexer.ResourceValueError(
                                    resource_type, "ended_at", ended_at)
                    r.ended_at = ended_at

                if kwargs:
                    for attribute, value in six.iteritems(kwargs):
                        if hasattr(r, attribute):
                            setattr(r, attribute, value)
                        else:
                            raise indexer.ResourceAttributeError(
                                r.type, attribute)

                if metrics is not _marker:
                    if not append_metrics:
                        session.query(Metric).filter(
                            Metric.resource_id == resource_id,
                            Metric.status == 'active').update(
                                {"resource_id": None})
                    self._set_metrics_for_resource(session, r, metrics)

                session.flush()
            except exception.DBConstraintError as e:
                if e.check_name == "ck_started_before_ended":
                    raise indexer.ResourceValueError(resource_type, "ended_at",
                                                     ended_at)
                raise

            # NOTE(jd) Force load of metrics – do it outside the session!
            r.metrics

            return r