# ----------------------------------------------------------------------- # Copyright © 2012 ShepHertz Technologies Pvt Ltd. All rights reserved. # ----------------------------------------------------------------------- require 'connection/RESTConnection' require 'util/util' require 'json/pure' require 'storage/StorageResponseBuilder' require 'storage/Storage' require 'storage/Query' require 'storage/QueryBuilder' require 'storage/OrderByType' module App42 module Storage # # Storage service on cloud provides the way to store the JSON document in NoSQL database running on cloud. # One can store the JSON document, update it , search it and can apply the map-reduce search on stored documents. # Example : If one will store JSON doc {"date":"5Feb"} it will be stored with unique Object Id and stored JSON object will look like # { "date" : "5Feb" , "_id" : { "$oid" : "4f423dcce1603b3f0bd560cf"}}. This oid can further be used to access/search the document. # # @see Storage # # @see App42Response # class StorageService # # this is a constructor that takes # # @param apiKey # @param secretKey # @param baseURL # def initialize(api_key, secret_key, base_url) puts "StorageService->initialize" @api_key = api_key @secret_key = secret_key @base_url = base_url @resource = "storage" @version = "1.0" end # # Save the JSON document in given database name and collection name. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc has to be saved. # @param json # - Target JSON document to be saved # # @return Storage object # # @raise App42Exception # def insert_json_document(dbName, collectionName, json) puts "Create Insert JSON Document Called " puts "Base url #{@base_url}" response = nil storage = nil storage = Storage.new util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName") util.throwExceptionIfNullOrBlank(collectionName, "CollectionName") util.throwExceptionIfNullOrBlank(json, "Json") begin connection = App42::Connection::RESTConnection.new(@base_url) body = {'app42' => {"storage"=> { "jsonDoc" => json }}}.to_json puts "Body #{body}" query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc } params.store("dbName", dbName) params.store("collectionName", collectionName) query_params = params.clone params.store("body", body) signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/insert/dbName/#{dbName}/collectionName/#{collectionName}" response = connection.post(signature, resource_url, query_params, body) storageObj = StorageResponseBuilder.new storage = storageObj.buildResponse(response) rescue App42Exception => e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Find all documents stored in given database and collection. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # # @return Storage object # # @raise App42Exception # def find_all_documents(dbName, collectionName) puts "Find All Documents Called " puts "Base url #{@base_url}" response = nil storage = nil storage = Storage.new() util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("dbName", dbName) params.store("collectionName", collectionName) signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findAll/dbName/#{dbName}/collectionName/#{collectionName}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new().buildResponse(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Gets the count of all documents stored in given database and collection. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # # @return App42Response object # # @raise App42Exception # def find_all_documents_count(dbName, collectionName) puts "Find All Documents Count Called " puts "Base url #{@base_url}" response = nil; responseObj = App42Response.new(); util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("dbName", dbName) params.store("collectionName", collectionName) signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findAll/count/dbName/#{dbName}/collectionName/#{collectionName}" response = connection.get(signature, resource_url, query_params) responseObj.strResponse=(response) responseObj.isResponseSuccess=(true) responseObj = StorageResponseBuilder.new() responseObj.getTotalRecords(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return responseObj end # # Find all documents stored in given database and collection. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param max # - Maximum number of records to be fetched # @param offset # - From where the records are to be fetched # # @return Storage object # # @raise App42Exception # def find_all_documents_by_paging(dbName, collectionName, max, offset) puts "Find All Documents Called " puts "Base url #{@base_url}" response = nil storageObj = nil storageObj = Storage.new() util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("dbName", dbName) params.store("collectionName", collectionName) params.store("max", "" + (max.to_i).to_s); params.store("offset", "" + (offset.to_i).to_s); signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findAll/dbName/#{dbName}/collectionName/#{collectionName}/#{(max.to_i).to_s}/#{(offset.to_i).to_s}" response = connection.get(signature, resource_url, query_params) storageObj = StorageResponseBuilder.new().buildResponse(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storageObj end # # Find target document by given unique object id. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param docId # - Unique Object Id handler. # # @return Storage object # # @raise App42Exception # def find_document_by_id(dbName, collectionName, docId) puts "Final Document By ID Called " puts "Base url #{@base_url}" response = nil storage = nil storage = Storage.new util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(docId, "DocumentId"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("dbName", dbName) params.store("collectionName", collectionName) params.store("docId", docId) signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findDocById/dbName/#{dbName}/collectionName/#{collectionName}/docId/#{docId}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new().buildResponse(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Find target document using key value search parameter. # This key value pair will be searched in the JSON doc stored on the cloud and matching Doc will be returned as a result of this method. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param key # - Key to be searched for target JSON doc. # @param value # - Value to be searched for target JSON doc. # # @return Storage object # # @raise App42Exception # def find_document_by_key_value(dbName, collectionName, key, value) puts "Find Document By Key Value Called" puts "Base url #{@base_url}" response = nil storage = nil storage = Storage.new util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(key, "Key"); util.throwExceptionIfNullOrBlank(value, "Value"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("dbName", dbName) params.store("collectionName", collectionName) params.store("key", key) params.store("value", value) puts query_params signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findDocByKV/dbName/#{dbName}/collectionName/#{collectionName}/#{key}/#{value}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new().buildResponse(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Update target document using key value search parameter. # # This key value pair will be searched in the JSON doc stored in the cloud and matching Doc will be updated with new value passed. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param key # - Key to be searched for target JSON doc. # @param value # - Value to be searched for target JSON doc. # @param newJsonDoc # - New Json document to be added. # # @return Storage object # # @raise App42Exception # def update_document_by_key_value(dbName, collectionName, key, value, newJsonDoc) puts "Update Document By Key Value Called" puts "Base url #{@base_url}" response = nil storageObj = nil storageObj = Storage.new util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(key, "Key"); util.throwExceptionIfNullOrBlank(value, "Value"); util.throwExceptionIfNullOrBlank(newJsonDoc, "NewJsonDocument"); begin connection = App42::Connection::RESTConnection.new(@base_url) body = {'app42' => {"storage"=> { "jsonDoc" => newJsonDoc }}}.to_json puts "Body #{body}" query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone params.store("body", body) params.store("dbName", dbName) params.store("collectionName", collectionName) params.store("key", key) params.store("value", value) puts query_params signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/update/dbName/#{dbName}/collectionName/#{collectionName}/#{key}/#{value}" response = connection.put(signature, resource_url, query_params,body) storage = StorageResponseBuilder.new().buildResponse(response); rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Delete target document using Object Id from given db and collection. # The Object Id will be searched in the JSON doc stored on the cloud and matching Doc will be deleted. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param docId # - Unique Object Id handler. # # @return App42Response object if deleted successfully # # @raise App42Exception # def delete_document_by_id(dbName, collectionName, docId) puts "Delete Document By ID Called " puts "Base url #{@base_url}" response = nil responseObj = App42Response.new(); util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(docId, "DocumentId"); begin connection = App42::Connection::RESTConnection.new(@base_url) util = Util.new query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } query_params = params.clone puts params params.store("dbName", dbName) params.store("collectionName", collectionName) params.store("docId", docId) puts query_params signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/deleteDocById/dbName/#{dbName}/collectionName/#{collectionName}/docId/#{docId}" response = connection.delete(signature, resource_url, query_params) responseObj.strResponse=(response) responseObj.isResponseSuccess=(true) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return responseObj end # # @param map # # @return # def get_json_from_map(map) return map.to_json end # # Save the JSON document in given database name and collection name. It accepts the HashMap containing key-value and convert it into JSON. # Converted JSON doc further saved on the cloud using given db name and collection name. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc has to be saved. # @param map # - HashMap containing key-value pairs # # @return Storage object # # @raise App42Exception # def insert_json_doc_using_map(dbName,collectionName,map) puts "insert_json_doc_using_map Called " puts "Base url #{@base_url}" jsonBody = get_json_from_map(map); return insert_json_document(dbName, collectionName, jsonBody) end # # Map reduce function to search the target document. # # Please see detail information on map-reduce http://en.wikipedia.org/wiki/MapReduce # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param mapFunction # - Map function to be used to search the document # @param reduceFunction # - Reduce function to be used to search the document # # @return Returns the target JSON document. # # @raise App42Exception # def map_reduce(dbName,collectionName,mapFunction,reduceFunction) response = nil util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(mapFunction, "MapFunction"); util.throwExceptionIfNullOrBlank(reduceFunction, "ReduceFunction"); begin connection = App42::Connection::RESTConnection.new(@base_url) body = {'app42' => {"storage"=> { "map" => mapFunction, "reduce" => reduceFunction }}}.to_json query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, } params.store("dbName", dbName) params.store("collectionName", collectionName) query_params = params.clone params.store("body", body) signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/mapReduce/dbName/#{dbName}/collectionName/#{collectionName}" response = connection.post(signature, resource_url, query_params, body) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return response end # # Update target document using the document id. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched. # @param docId # - Id of the document to be searched for target JSON doc. # @param newJsonDoc # - New Json document to be added. # # @return Storage object # # @raise App42Exception # def update_document_by_doc_id(dbName, collectionName, docId, newJsonDoc) puts "Update Document By Document Id Called " puts "Base url #{@base_url}" response = nil storage = nil storage = Storage.new util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName") util.throwExceptionIfNullOrBlank(collectionName, "CollectionName") util.throwExceptionIfNullOrBlank(docId, "DocId"); util.throwExceptionIfNullOrBlank(newJsonDoc, "NewJsonDocument"); begin connection = App42::Connection::RESTConnection.new(@base_url) body = {'app42' => {"storage"=> { "jsonDoc" => newJsonDoc }}}.to_json puts "Body #{body}" query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc } params.store("body", body) params.store("docId", docId) params.store("dbName", dbName) params.store("collectionName", collectionName) query_params = params.clone signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/updateByDocId/dbName/#{dbName}/collectionName/#{collectionName}/docId/#{docId}" response = connection.put(signature, resource_url, query_params, body) storageObj = StorageResponseBuilder.new storage = storageObj.buildResponse(response) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storage end # # Find target document using Custom Query. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched # @param Query # - Query Object containing custom query for searching docs # # @return Storage object # # @raise App42Exception # def find_document_by_query(dbName, collectionName, query) puts "find_document_by_query Called " puts "Base url #{@base_url}" response = nil storageObj = nil storageObj = Storage.new() util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(query, "query"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, 'jsonQuery' => query.getStr() } params.store("dbName", dbName); params.store("collectionName", collectionName); query_params = params.clone signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findDocsByQuery/dbName/#{dbName}/collectionName/#{collectionName}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new storageObj = storage.buildResponse(response) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storageObj end # # Find target document using Custom Query with paging. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched # @param Query # - Query Object containing custom query for searching docs # @param max # - max result parameter # @param offset # - offset result parameter # # @return Storage object # # @raise App42Exception # def find_documents_by_query_with_paging(dbName, collectionName, query, max, offset) puts "findDocumentsByQueryWithPaging Called " puts "Base url #{@base_url}" response = nil storageObj = nil storageObj = Storage.new() util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(query, "query"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, 'jsonQuery' => query.getStr() } params.store("dbName", dbName); params.store("collectionName", collectionName); params.store("max", "" + (max.to_i).to_s) params.store("offset", "" + (offset.to_i).to_s) query_params = params.clone signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findDocsByQuery/dbName/#{dbName}/collectionName/#{collectionName}/#{(max.to_i).to_s}/#{(offset.to_i).to_s}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new storageObj = storage.buildResponse(response) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storageObj end # # Find target document using Custom Query with paging and orderby. # # @param dbName # - Unique handler for storage name # @param collectionName # - Name of collection under which JSON doc needs to be searched # @param Query # - Query Object containing custom query for searching docs # @param max # - max result parameter # @param offset # - offset result parameter # # @return Storage object # # @raise App42Exception # def find_docs_with_query_paging_order_by(dbName, collectionName, query, max, offset, orderByKey, type) puts "findDocsWithQueryPagingOrderBy Called " puts "Base url #{@base_url}" response = nil storageObj = nil storageObj = Storage.new() util = Util.new util.throwExceptionIfNullOrBlank(dbName, "DataBaseName"); util.throwExceptionIfNullOrBlank(collectionName, "CollectionName"); util.throwExceptionIfNullOrBlank(query, "query"); begin connection = App42::Connection::RESTConnection.new(@base_url) query_params = Hash.new params = { 'apiKey'=> @api_key, 'version' => @version, 'timeStamp' => util.get_timestamp_utc, 'jsonQuery' => query.getStr() } if (orderByKey != nil) query_params.store("orderByKey", orderByKey); end if (type != nil) query_params.store("orderByType", type); end params.store("dbName", dbName); params.store("collectionName", collectionName); params.store("max", "" + (max.to_i).to_s) params.store("offset", "" + (offset.to_i).to_s) query_params = params.clone signature = util.sign(@secret_key, params) resource_url = "#{@version}/#{@resource}/findDocsByQuery/dbName/#{dbName}/collectionName/#{collectionName}/#{(max.to_i).to_s}/#{(offset.to_i).to_s}" response = connection.get(signature, resource_url, query_params) storage = StorageResponseBuilder.new storageObj = storage.buildResponse(response) rescue App42Exception =>e raise e rescue Exception => e raise App42Exception.new(e) end return storageObj end end end end