From c9ec15aa9bf5c19bddb9c4457e233e1000923ae4 Mon Sep 17 00:00:00 2001 From: leenasn Date: Mon, 16 Nov 2015 19:07:29 +0530 Subject: [PATCH] Add GCM push for pushing OneMDM app to devices --- app/admin/dashboard.rb | 60 +++++++++++-------- app/admin/device.rb | 27 +++++---- app/controllers/application_controller.rb | 4 ++ app/models/app.rb | 7 +++ app/models/batch_installation.rb | 2 + app/models/device.rb | 1 + app/models/installation.rb | 23 ++++++- config/application.rb | 2 + config/environments/development.rb | 2 +- config/initializers/active_admin.rb | 5 +- config/initializers/rollbar.rb | 2 +- config/routes.rb | 2 +- .../20151113123015_create_applications.rb | 2 +- ...0151113124226_rename_application_to_app.rb | 5 -- ...151113131647_create_batch_installations.rb | 3 +- .../20151113132152_create_installations.rb | 6 +- db/schema.rb | 14 ++++- spec/factories/app.rb | 4 +- spec/factories/batch_installations.rb | 2 +- spec/factories/installations.rb | 5 +- spec/models/app.rb | 11 ---- spec/models/installation_spec.rb | 18 +++++- 22 files changed, 131 insertions(+), 76 deletions(-) delete mode 100644 db/migrate/20151113124226_rename_application_to_app.rb delete mode 100644 spec/models/app.rb diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb index eae7baf..0fd077d 100644 --- a/app/admin/dashboard.rb +++ b/app/admin/dashboard.rb @@ -3,31 +3,41 @@ ActiveAdmin.register_page "Dashboard" do menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") } content title: proc{ I18n.t("active_admin.dashboard") } do - div class: "blank_slate_container", id: "dashboard_default_message" do - span class: "blank_slate" do - span I18n.t("active_admin.dashboard_welcome.welcome") - small I18n.t("active_admin.dashboard_welcome.call_to_action") + + panel "Recent Pushes" do + table_for BatchInstallation.order('id desc').limit(10) do + column "Pushed on" do |batch| + batch.created_at + end + column "App Name" do |batch| + batch.app.name + end + column "# Devices" do |batch| + link_to batch.installations.count, + admin_devices_path(q: {installations_batch_installation_id_eq: batch.id}) + end + column "# Installed" do |batch| + link_to batch.installations.installed.count, + admin_devices_path(q: {installations_batch_installation_id_eq: batch.id, + installations_status_eq: Installation.statuses[:installed]}) + end + column "# Cancelled" do |batch| + link_to batch.installations.cancelled.count, + admin_devices_path(q: {installations_batch_installation_id_eq: batch.id, + installations_status_eq: Installation.statuses[:cancelled]}) + end + column "# Pending" do |batch| + link_to batch.installations.pushed.count + batch.installations.downloaded.count, + admin_devices_path(q: {installations_batch_installation_id_eq: batch.id, + installations_status_in: [Installation.statuses[:pushed], + Installation.statuses[:downloaded]]}) + end + column "% Success" do |batch| + total = batch.installations.count + installed = batch.installations.installed.count + percentage_success = (installed/total) * 100 if total > 0 + end end - end - - # Here is an example of a simple dashboard with columns and panels. - # - # columns do - # column do - # panel "Recent Posts" do - # ul do - # Post.recent(5).map do |post| - # li link_to(post.title, admin_post_path(post)) - # end - # end - # end - # end - - # column do - # panel "Info" do - # para "Welcome to ActiveAdmin." - # end - # end - # end + end end # content end diff --git a/app/admin/device.rb b/app/admin/device.rb index 1b18cc0..3150d92 100644 --- a/app/admin/device.rb +++ b/app/admin/device.rb @@ -2,18 +2,21 @@ ActiveAdmin.register Device do actions :all, except: [:edit,:new] -# See permitted parameters documentation: -# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters -# -# permit_params :list, :of, :attributes, :on, :model -# -# or -# -# permit_params do -# permitted = [:permitted, :attributes] -# permitted << :other if resource.something? -# permitted -# end + app_data = lambda do + apps = App.order('name').reload.pluck(:name,:id) + {"App Name" => apps} + end + + batch_action :push, confirm: "Select apps to push",form: app_data do |ids,inputs| + app = App.find(inputs["App Name"]) + batch = BatchInstallation.create(:app => app) + ids.each do | id | + install = Installation.new(device: Device.find(id),batch_installation: batch) + install.pushed! + end + redirect_to admin_dashboard_path, notice: "Successfully pushed app to device(s)" + end + index do selectable_column id_column diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 99ce66c..7fd59b6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -17,4 +17,8 @@ class ApplicationController < ActionController::Base def render_unauthorized render json: "Bad token", status: :unauthorised end + + def set_timezone_for_admin + Time.zone = "Mumbai" + end end diff --git a/app/models/app.rb b/app/models/app.rb index d3e15e6..abf5c39 100644 --- a/app/models/app.rb +++ b/app/models/app.rb @@ -1,4 +1,11 @@ class App < ActiveRecord::Base + has_many :batch_installations, dependent: :destroy + validates :name, :package_name, presence: true + + def apk_url + return DEFAULT_APP_URL if self.package_name.eql?(DEFAULT_APP_PACKAGE_NAME) + "" + end end diff --git a/app/models/batch_installation.rb b/app/models/batch_installation.rb index 4f7e556..b73652f 100644 --- a/app/models/batch_installation.rb +++ b/app/models/batch_installation.rb @@ -1,3 +1,5 @@ class BatchInstallation < ActiveRecord::Base belongs_to :app + + has_many :installations, dependent: :destroy end diff --git a/app/models/device.rb b/app/models/device.rb index d798c9a..c0b9cb6 100644 --- a/app/models/device.rb +++ b/app/models/device.rb @@ -10,6 +10,7 @@ class Device < ActiveRecord::Base after_create :update_last_heartbeats_time has_many :heartbeats, dependent: :destroy + has_many :installations, dependent: :destroy scope :active, -> {where("last_heartbeat_recd_time > '#{Time.now.utc - ACTIVE_TIMEFRAME}'")} scope :missing, -> {where("last_heartbeat_recd_time < '#{Time.now.utc - ACTIVE_TIMEFRAME}'AND last_heartbeat_recd_time > '#{Time.now.utc - MISSING_TIMEFRAME}'")} diff --git a/app/models/installation.rb b/app/models/installation.rb index d3d0a24..e2d00e7 100644 --- a/app/models/installation.rb +++ b/app/models/installation.rb @@ -1,9 +1,28 @@ class Installation < ActiveRecord::Base enum status: [:pushed, :downloaded, :cancelled, :installed] - - + delegate :app, to: :batch_installation belongs_to :device belongs_to :batch_installation + after_create :push_apps + + def as_json(options={}) + { + :id => self.id, + :name => self.app.name, + :package_name => self.app.package_name, + :apk_url => self.app.apk_url + } + end + + def push_apps + if self.pushed? + gcm = GCM.new(GCM_KEY) + registration_ids = [self.device.gcm_token] + options = { data: {message: self.to_json }} + response = gcm.send(registration_ids, options) + logger.debug "response #{response}" + end + end end diff --git a/config/application.rb b/config/application.rb index 684c134..2442bb8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,3 +37,5 @@ module OnemdmServer end STATUS_CLASSES = {active: :ok,missing: :warning,dead: :error} GCM_KEY = "AIzaSyCZ3lVhV2CbIcZ22f1YI_MvPx3C7sMm_2g" +DEFAULT_APP_PACKAGE_NAME = "com.multunus.onemdm" +DEFAULT_APP_URL = "https://s3.amazonaws.com/onemdm/onemdm.apk" diff --git a/config/environments/development.rb b/config/environments/development.rb index daede1e..6cf3b77 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -42,5 +42,5 @@ Rails.application.configure do ACTIVE_TIMEFRAME = 1.hours MISSING_TIMEFRAME = 2.hours - + #DEFAULT_APP_URL = "http://192.168.2.92:3000/onemdm.apk" end diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb index cd683d2..c7bf66e 100644 --- a/config/initializers/active_admin.rb +++ b/config/initializers/active_admin.rb @@ -119,7 +119,7 @@ ActiveAdmin.setup do |config| # This allows your users to comment on any resource registered with Active Admin. # # You can completely disable comments: - # config.comments = false + config.comments = false # # You can disable the menu item for the comments index page: # config.show_comments_in_menu = false @@ -259,6 +259,7 @@ ActiveAdmin.setup do |config| # You can enable or disable them for all resources here. # # config.filters = true + config.current_filters = false # # By default the filters include associations in a select, which means # that every record will be loaded for each association. @@ -266,4 +267,6 @@ ActiveAdmin.setup do |config| # of those filters by default here. # # config.include_default_association_filters = true + + config.before_filter :set_timezone_for_admin end diff --git a/config/initializers/rollbar.rb b/config/initializers/rollbar.rb index 393f2da..3a1858d 100644 --- a/config/initializers/rollbar.rb +++ b/config/initializers/rollbar.rb @@ -5,7 +5,7 @@ Rollbar.configure do |config| config.access_token = ENV['ROLLBAR_ACCESS_TOKEN'] # Here we'll disable in 'test': - if Rails.env.test? + if Rails.env.test? || Rails.env.development? config.enabled = false end diff --git a/config/routes.rb b/config/routes.rb index 75ed72d..db1b9f9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,7 +8,7 @@ Rails.application.routes.draw do # See how all your routes lay out with "rake routes". # You can have the root of your site routed with "root" - # root 'welcome#index' + root 'admin/dashboard#index' # Example of regular route: # get 'products/:id' => 'catalog#view' diff --git a/db/migrate/20151113123015_create_applications.rb b/db/migrate/20151113123015_create_applications.rb index 61cc006..eaf2dd9 100644 --- a/db/migrate/20151113123015_create_applications.rb +++ b/db/migrate/20151113123015_create_applications.rb @@ -1,6 +1,6 @@ class CreateApplications < ActiveRecord::Migration def change - create_table :applications do |t| + create_table :apps do |t| t.string :name t.string :package_name diff --git a/db/migrate/20151113124226_rename_application_to_app.rb b/db/migrate/20151113124226_rename_application_to_app.rb deleted file mode 100644 index 7e503b0..0000000 --- a/db/migrate/20151113124226_rename_application_to_app.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameApplicationToApp < ActiveRecord::Migration - def change - rename_table :applications, :apps - end -end diff --git a/db/migrate/20151113131647_create_batch_installations.rb b/db/migrate/20151113131647_create_batch_installations.rb index b950f95..b99d921 100644 --- a/db/migrate/20151113131647_create_batch_installations.rb +++ b/db/migrate/20151113131647_create_batch_installations.rb @@ -1,8 +1,7 @@ class CreateBatchInstallations < ActiveRecord::Migration def change create_table :batch_installations do |t| - t.integer :app_id - + t.belongs_to :app, foreign_key: true, index: true t.timestamps null: false end end diff --git a/db/migrate/20151113132152_create_installations.rb b/db/migrate/20151113132152_create_installations.rb index 6aaa6c9..219cde5 100644 --- a/db/migrate/20151113132152_create_installations.rb +++ b/db/migrate/20151113132152_create_installations.rb @@ -1,9 +1,9 @@ class CreateInstallations < ActiveRecord::Migration def change create_table :installations do |t| - t.integer :device_id - t.integer :batch_installation_id - t.integer :status + t.belongs_to :device, foreign_key: true, index: true + t.belongs_to :batch_installation, foreign_key: true, index: true + t.integer :status, default: 0, null: false t.timestamps null: false end diff --git a/db/schema.rb b/db/schema.rb index a56d2b8..c2e80dc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -62,6 +62,8 @@ ActiveRecord::Schema.define(version: 20151113140645) do t.datetime "updated_at", null: false end + add_index "batch_installations", ["app_id"], name: "index_batch_installations_on_app_id", using: :btree + create_table "devices", force: :cascade do |t| t.string "model" t.string "unique_id" @@ -85,10 +87,16 @@ ActiveRecord::Schema.define(version: 20151113140645) do create_table "installations", force: :cascade do |t| t.integer "device_id" t.integer "batch_installation_id" - t.integer "status" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "status", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end + add_index "installations", ["batch_installation_id"], name: "index_installations_on_batch_installation_id", using: :btree + add_index "installations", ["device_id"], name: "index_installations_on_device_id", using: :btree + + add_foreign_key "batch_installations", "apps" add_foreign_key "heartbeats", "devices" + add_foreign_key "installations", "batch_installations" + add_foreign_key "installations", "devices" end diff --git a/spec/factories/app.rb b/spec/factories/app.rb index 25f9e7c..d9591fc 100644 --- a/spec/factories/app.rb +++ b/spec/factories/app.rb @@ -1,7 +1,7 @@ FactoryGirl.define do factory :app do - name "My Ultimate Application" - package_name "my.ultimate.application" + name "One MDM" + package_name "com.multunus.onemdm" end end diff --git a/spec/factories/batch_installations.rb b/spec/factories/batch_installations.rb index 5bb7557..fbf7434 100644 --- a/spec/factories/batch_installations.rb +++ b/spec/factories/batch_installations.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :batch_installation do - app_id 1 + association :app end end diff --git a/spec/factories/installations.rb b/spec/factories/installations.rb index 8795f38..525a8ff 100644 --- a/spec/factories/installations.rb +++ b/spec/factories/installations.rb @@ -1,8 +1,7 @@ FactoryGirl.define do factory :installation do - device_id 1 - batch_installation_id 1 - status 1 + association :device + association :batch_installation end end diff --git a/spec/models/app.rb b/spec/models/app.rb deleted file mode 100644 index cc86d18..0000000 --- a/spec/models/app.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'rails_helper' - -RSpec.describe App, type: :model do - pending "add some examples to (or delete) #{__FILE__}" - - let!(:app) { create(:app) } - - it { should validate_presence_of :name } - it { should validate_presence_of :package_name } - -end diff --git a/spec/models/installation_spec.rb b/spec/models/installation_spec.rb index d2fb891..a6a6a9e 100644 --- a/spec/models/installation_spec.rb +++ b/spec/models/installation_spec.rb @@ -4,11 +4,12 @@ RSpec.describe Installation, type: :model do it { should belong_to(:device) } it { should belong_to(:batch_installation) } - - # Create Installation Model [Device ID, batch installation ID, status(Pushed, Downloaded, Cancelled, Installed)] describe "Installation status" do let!(:installation){FactoryGirl.create(:installation)} + it "Default status" do + expect(installation.status).to eql Installation.statuses.keys[0] + end it "Pushed" do installation.pushed! expect(installation.status).to eql Installation.statuses.keys[0] @@ -29,4 +30,17 @@ RSpec.describe Installation, type: :model do end + describe "GCM Push " do + let(:installation){FactoryGirl.build(:installation)} + + it "if status is pushed" do + expect_any_instance_of(GCM).to receive(:send).and_return(installation) + installation.save + end + it "status is not pushed" do + expect_any_instance_of(GCM).not_to receive(:send) + installation.cancelled! + end + end + end