Merge branch 'main' into api
diff --git a/staffeln/api/app.py b/staffeln/api/app.py
index 90f35df..62865f7 100755
--- a/staffeln/api/app.py
+++ b/staffeln/api/app.py
@@ -1,21 +1,42 @@
 from flask import Flask

+from flask import Response

 from flask import jsonify

 from flask import request

+from staffeln import objects

+from staffeln.common import context

+from staffeln.common import auth

+from oslo_log import log

+from openstack import exceptions as exc

 

 

+ctx = context.make_context()

 app = Flask(__name__)

 

+LOG = log.getLogger(__name__)

 

-@app.route('/')

-def hello_world():

-    return 'This is my first API call!'

+conn = auth.create_connection()

 

 

-@app.route('/post', methods=["POST"])

-def testpost():

-    input_json = request.get_json(force=True)

-    dictToReturn = {'text': input_json['text']}

-    return jsonify(dictToReturn)

+@app.route("/v1/backup", methods=["GET"])

+def backup_id():

+    if "backup_id" not in request.args:

+        # Return error if the backup_id argument is not provided.

+        return "Error: No backup_id field provided. Please specify backup_id."

+

+    backup_id = request.args["backup_id"]

+    # Retrive the backup object from backup_data table with matching backup_id.

+    backup = objects.Volume.get_backup_by_backup_id(ctx, backup_id)

+    # backup_info is None when there is no entry of the backup id in backup_table.

+    # So the backup should not be the automated backup.

+    if backup is None:

+        return Response(

+            "True",

+            status=200,

+            mimetype="text/plain",

+        )

+    else:

+        return Response("Deny", status=401, mimetype="text/plain")

+

 

 def run(host, port, ssl_context):

     app.run(host=host, port=port, ssl_context=ssl_context)

diff --git a/staffeln/db/sqlalchemy/api.py b/staffeln/db/sqlalchemy/api.py
index 6ba5183..4b4fc9f 100644
--- a/staffeln/db/sqlalchemy/api.py
+++ b/staffeln/db/sqlalchemy/api.py
@@ -109,6 +109,7 @@
         if filters is None:
             filters = {}
 
+
         plain_fields = ["volume_id", "backup_id", "backup_completed", "instance_id", "created_at"]
 
         return self._add_filters(
@@ -181,7 +182,8 @@
         query = query.filter(getattr(model, fieldname) == value)
 
         try:
-            obj = query.one()
+            # To avoid exception if the no result found in table.
+            obj = query.one_or_none()
         except exc.NoResultFound:
             LOG.error("ResourceNotFound")
 
@@ -280,7 +282,7 @@
         )
 
     def update_queue(self, id, values):
-        print(self._update(models.Queue_data, id, values))
+
         try:
             return self._update(models.Queue_data, id, values)
         except:
@@ -307,8 +309,28 @@
         except:
             LOG.error("Queue Not found.")
 
+
+    def get_backup_by_backup_id(self, context, backup_id):
+        """Get the column from the backup_data with matching backup_id"""
+
+        try:
+            return self._get_backup(context, fieldname="backup_id", value=backup_id)
+        except:
+            LOG.error("Backup not found with backup_id %s." % backup_id)
+
+    def _get_backup(self, context, fieldname, value):
+        """Get the column from the volume_data table"""
+
+        try:
+            return self._get(
+                context, model=models.Backup_data, fieldname=fieldname, value=value
+            )
+        except:
+            LOG.error("Backup resource not found.")
+
+
     def soft_delete_backup(self, id):
         try:
             return self._soft_delete(models.Backup_data, id)
         except:
-            LOG.error("Backup Not found.")
\ No newline at end of file
+            LOG.error("Backup Not found.")
diff --git a/staffeln/objects/volume.py b/staffeln/objects/volume.py
index 276dd2e..6655b7b 100644
--- a/staffeln/objects/volume.py
+++ b/staffeln/objects/volume.py
@@ -63,3 +63,23 @@
     def delete_backup(self):
         """Soft Delete the :class:`Queue_data` from the DB"""
         db_obj = self.dbapi.soft_delete_backup(self.id)
+
+    @base.remotable_classmethod
+    def get_backup_by_backup_id(cls, context, backup_id):
+        """Find a backup based on backup_id
+        :param context: Security context. NOTE: This should only
+                        be used internally by the indirection_api.
+                        Unfortunately, RPC requires context as the first
+                        argument, even though we don't use it.
+                        A context should be set when instantiating the
+                        object, e.g.: Queue(context)
+        :param backup_id: the backup id of volume in volume data.
+        :returns: a :class:`Backup` object.
+        """
+        db_backup = cls.dbapi.get_backup_by_backup_id(context, backup_id)
+        if db_backup is None:
+            return db_backup
+        else:
+            backup = cls._from_db_object(cls(context), db_backup)
+            return backup
+          
\ No newline at end of file