Resolve conflicts in strucutre.sql

pull/1080/head
Rick Carlino 2019-01-07 15:04:42 -06:00
commit 4248c8fe4a
20 changed files with 2117 additions and 1592 deletions

View File

@ -35,8 +35,6 @@ gem "redis", "~> 4.0"
group :development, :test do
gem "thin"
gem "capybara"
# gem "deep-cover", "~> 0.4", require: false
gem "codecov", require: false
gem "simplecov"
gem "database_cleaner"

View File

@ -7,25 +7,25 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (5.2.1)
actionpack (= 5.2.1)
actioncable (5.2.2)
actionpack (= 5.2.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.1)
actionpack (= 5.2.1)
actionview (= 5.2.1)
activejob (= 5.2.1)
actionmailer (5.2.2)
actionpack (= 5.2.2)
actionview (= 5.2.2)
activejob (= 5.2.2)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.1)
actionview (= 5.2.1)
activesupport (= 5.2.1)
actionpack (5.2.2)
actionview (= 5.2.2)
activesupport (= 5.2.2)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.1)
activesupport (= 5.2.1)
actionview (5.2.2)
activesupport (= 5.2.2)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@ -35,20 +35,20 @@ GEM
activemodel (>= 4.1, < 6)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (5.2.1)
activesupport (= 5.2.1)
activejob (5.2.2)
activesupport (= 5.2.2)
globalid (>= 0.3.6)
activemodel (5.2.1)
activesupport (= 5.2.1)
activerecord (5.2.1)
activemodel (= 5.2.1)
activesupport (= 5.2.1)
activemodel (5.2.2)
activesupport (= 5.2.2)
activerecord (5.2.2)
activemodel (= 5.2.2)
activesupport (= 5.2.2)
arel (>= 9.0)
activestorage (5.2.1)
actionpack (= 5.2.1)
activerecord (= 5.2.1)
activestorage (5.2.2)
actionpack (= 5.2.2)
activerecord (= 5.2.2)
marcel (~> 0.3.1)
activesupport (5.2.1)
activesupport (5.2.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@ -56,21 +56,13 @@ GEM
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
amq-protocol (2.3.0)
appsignal (2.7.2)
appsignal (2.8.1)
rack
arel (9.0.0)
bcrypt (3.1.12)
builder (3.2.3)
bunny (2.12.0)
bunny (2.13.0)
amq-protocol (~> 2.3, >= 2.3.0)
capybara (3.11.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.2)
xpath (~> 3.2)
case_transform (0.2)
activesupport
childprocess (0.9.0)
@ -82,7 +74,7 @@ GEM
simplecov
url
coderay (1.1.2)
concurrent-ruby (1.1.3)
concurrent-ruby (1.1.4)
crass (1.0.4)
daemons (1.2.6)
database_cleaner (1.7.0)
@ -103,8 +95,7 @@ GEM
discard (1.0.0)
activerecord (>= 4.2, < 6)
docile (1.3.1)
effin_utf8 (1.0)
erubi (1.7.1)
erubi (1.8.0)
eventmachine (1.2.7)
excon (0.62.0)
factory_bot (4.11.1)
@ -159,17 +150,17 @@ GEM
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
hashdiff (0.3.7)
hashdiff (0.3.8)
hashie (3.6.0)
httpclient (2.8.3)
i18n (1.1.1)
i18n (1.4.0)
concurrent-ruby (~> 1.0)
json (2.1.0)
jsonapi-renderer (0.2.0)
jwt (2.1.0)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.6.0)
letter_opener (1.7.0)
launchy (~> 2.2)
lol_dba (2.1.5)
actionpack (>= 3.0)
@ -187,17 +178,17 @@ GEM
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812)
mimemagic (0.3.2)
mimemagic (0.3.3)
mini_mime (1.0.1)
mini_portile2 (2.3.0)
mini_portile2 (2.4.0)
minitest (5.11.3)
multi_json (1.13.1)
multipart-post (2.0.0)
mutations (0.8.3)
activesupport
nio4r (2.3.1)
nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
nokogiri (1.9.1)
mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0)
os (1.0.0)
paperclip (6.1.0)
@ -206,7 +197,7 @@ GEM
mime-types
mimemagic (~> 0.3.0)
terrapin (~> 0.6.0)
passenger (5.3.7)
passenger (6.0.0)
rack
rake (>= 0.8.1)
pg (1.1.3)
@ -215,11 +206,10 @@ GEM
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-rails (0.3.7)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (3.0.3)
rabbitmq_http_api_client (1.9.1)
effin_utf8 (~> 1.0.0)
rabbitmq_http_api_client (1.11.0)
faraday (~> 0.13.0)
faraday_middleware (~> 0.12.0)
hashie (~> 3.5)
@ -230,18 +220,18 @@ GEM
rack-cors (1.0.2)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.1)
actioncable (= 5.2.1)
actionmailer (= 5.2.1)
actionpack (= 5.2.1)
actionview (= 5.2.1)
activejob (= 5.2.1)
activemodel (= 5.2.1)
activerecord (= 5.2.1)
activestorage (= 5.2.1)
activesupport (= 5.2.1)
rails (5.2.2)
actioncable (= 5.2.2)
actionmailer (= 5.2.2)
actionpack (= 5.2.2)
actionview (= 5.2.2)
activejob (= 5.2.2)
activemodel (= 5.2.2)
activerecord (= 5.2.2)
activestorage (= 5.2.2)
activesupport (= 5.2.2)
bundler (>= 1.3.0)
railties (= 5.2.1)
railties (= 5.2.2)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
@ -258,15 +248,14 @@ GEM
rails_stdout_logging
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (5.2.1)
actionpack (= 5.2.1)
activesupport (= 5.2.1)
railties (5.2.2)
actionpack (= 5.2.2)
activesupport (= 5.2.2)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rake (12.3.1)
redis (4.0.3)
regexp_parser (1.3.0)
rake (12.3.2)
redis (4.1.0)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
@ -277,7 +266,7 @@ GEM
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
retriable (3.1.2)
rollbar (2.18.0)
rollbar (2.18.2)
multi_json
rspec (3.8.0)
rspec-core (~> 3.8.0)
@ -319,9 +308,9 @@ GEM
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
skylight (3.1.1)
skylight-core (= 3.1.1)
skylight-core (3.1.1)
skylight (3.1.2)
skylight-core (= 3.1.2)
skylight-core (3.1.2)
activesupport (>= 4.2.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
@ -352,8 +341,6 @@ GEM
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
zero_downtime_migrations (0.0.7)
activerecord
@ -364,7 +351,6 @@ DEPENDENCIES
active_model_serializers
appsignal
bunny
capybara
climate_control
codecov
database_cleaner

View File

@ -2,9 +2,9 @@ class SendNervesHubInfoJob < ApplicationJob
queue_as :default
def perform(device_id:, serial_number:, tags:)
device = Device.find(device_id)
DeviceSerialNumber.transaction do
DeviceSerialNumber.create!(device_id: device_id,
serial_number: serial_number)
device.update_attributes!(serial_number: serial_number)
resp_data = NervesHub.create_or_update(serial_number, tags)
certs = NervesHub.sign_device(resp_data.fetch(:identifier))
Transport.current.amqp_send(certs.to_json, device_id, "nerves_hub")

View File

@ -1,7 +1,6 @@
require "net/http"
require "openssl"
require "base64"
class NervesHub
class NervesHubHTTPError < StandardError; end
# There is a lot of configuration available in this class to support:
@ -68,12 +67,28 @@ class NervesHub
raise NervesHubHTTPError, NERVES_HUB_ERROR % [code, body]
end
APPLICATION = "application"
CHANNEL = "channel"
def self.update_channel(serial_number, channel)
dev = device(serial_number)
return unless dev
# ["application:prod", "channel:stable"]
# Becomes: {"application"=>"prod", "channel"=>"stable"}
# NEVER DUPLICATE TAG PREFIXES (thing before ":"). Must be unique!
tag_map = dev.fetch(:tags).map { |x| x.split(":") }.to_h
tag_map[CHANNEL] = channel
next_tags = tag_map.to_a.map { |x| x.join(":") }
update(serial_number, next_tags)
end
# Checks if a deivce exists in NervesHub
# if it does -> does a PUT request updating the tags.
# if it does not -> does a POST request creating the device with given tags.
def self.create_or_update(serial_number, tags)
current_nerves_hub_devcice = device(serial_number)
if current_nerves_hub_devcice
# Hash | nil
current_nerves_hub_device = device(serial_number)
if current_nerves_hub_device
update(serial_number, tags)
else
new_device(serial_number, tags)
@ -161,7 +176,7 @@ class NervesHub
# HTTP connection.
def self.conn
active? && !@conn ? set_conn : @conn
(active? && !@conn) ? set_conn : @conn
end
private

View File

@ -41,7 +41,11 @@ class ApplicationRecord < ActiveRecord::Base
def force_serialization
serializer = ActiveModel::Serializer.serializer_for(self)
return (serializer ? serializer.new(self) : self).as_json
if serializer
serializer.new(self).as_json
else
self.as_json
end
end
def broadcast_payload(label)

View File

@ -32,6 +32,7 @@ class Device < ApplicationRecord
has_many :diagnostic_dumps, dependent: :destroy
has_many :fragments, dependent: :destroy
has_one :fbos_config, dependent: :destroy
has_one :device_serial_number, dependent: :destroy
has_many :in_use_tools
has_many :in_use_points
has_many :users

View File

@ -1,3 +1,4 @@
class DeviceSerialNumber < ApplicationRecord
belongs_to :device
# DO NOT USE THIS TABLE. IT IS DEPRECATED. DESTROY FEB 2019.
end

View File

@ -1,4 +1,27 @@
# An API backup of user options for Farmbot OS.
class FbosConfig < ApplicationRecord
class MissingSerial < StandardError; end
belongs_to :device
after_save :maybe_sync_nerves, on: [:create, :update]
NERVES_FIELD = "update_channel"
def push_changes_to_nerves_hub(serial_number, channel)
NervesHub.update_channel(serial_number, channel)
end
def sync_nerves
serial = device.serial_number
return unless serial
self.delay.push_changes_to_nerves_hub(serial, update_channel)
end
def nerves_info_changed?
the_changes.keys.include?(NERVES_FIELD)
end
def maybe_sync_nerves
sync_nerves if nerves_info_changed?
end
end

View File

@ -1,4 +1,6 @@
class DeviceSerializer < ApplicationSerializer
attributes :name, :timezone, :last_saw_api, :last_saw_mq, :tz_offset_hrs,
:fbos_version, :throttled_until, :throttled_at, :mounted_tool_id
attributes :fbos_version, :last_saw_api, :last_saw_mq,
:mounted_tool_id, :name, :serial_number,
:throttled_at, :throttled_until, :timezone,
:tz_offset_hrs
end

View File

@ -0,0 +1,5 @@
class AddSerialNumberToDevice < ActiveRecord::Migration[5.2]
def change
add_column :devices, :serial_number, :string, limit: 32
end
end

View File

@ -0,0 +1,8 @@
class DeprecateDeviceSerialNumberTable < ActiveRecord::Migration[5.2]
def change
DeviceSerialNumber.preload(:devices) do |x|
x.device
.update_attributes!(serial_number: x.serial_number)
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@ services:
- ./docker_volumes/rabbit:/farmbot
webpack: # ====================
<<: *base_config
image: node:8.12.0
image: node:10.15.0
working_dir: /farmbot
command: ./node_modules/.bin/webpack-dev-server --config config/webpack.config.js
volumes:

View File

@ -44,7 +44,7 @@
"@types/react": "^16.7.13",
"@types/react-color": "2.13.6",
"@types/react-dom": "^16.0.11",
"@types/react-joyride": "^2.0.1",
"@types/react-joyride": "2.0.1",
"@types/react-redux": "^6.0.10",
"axios": "^0.18.0",
"boxed_value": "^1.0.0",

View File

@ -58,7 +58,7 @@ describe Api::DeviceCertsController do
end
expect(response.status).to eq(200)
expect(json).to eq({})
expect(DeviceSerialNumber.count).to be > old_count
expect(DeviceSerialNumber.count).to eq(old_count)
end
end
end

View File

@ -1,6 +1,6 @@
FactoryBot.define do
factory :device_serial_number do
device { nil }
serial_number { "" }
serial_number { raise "Stop using this model" }
end
end

View File

@ -2,5 +2,6 @@ FactoryBot.define do
factory :device do
name { Faker::Food.vegetables }
timezone { Device::TIMEZONES.sample }
serial_number { SecureRandom.hex(16)}
end
end

View File

@ -1,14 +1,6 @@
require "spec_helper"
describe NervesHub do
class StubResp
attr_accessor :code, :body
def initialize(code, body)
@code, @body = code, body
end
end
def stub_connection
double(SecureRandom.hex.first(6), :ca_file= => nil,
:cert_store => nil,

View File

@ -0,0 +1,29 @@
require 'spec_helper'
describe FbosConfig do
let(:device) { FactoryBot.create(:device) }
let(:config) { FbosConfig.create!(device: device) }
it 'triggers callbacks' do
conn = double("Create a cert", :ca_file= => nil,
:cert_store => nil,
:cert_store= => nil,
:use_ssl => nil,
:use_ssl= => nil,
:cert= => nil,
:key= => nil)
NervesHub.set_conn(conn)
url = "/orgs/farmbot/devices/#{device.serial_number}"
resp = StubResp.new("200", { "data" => { "tags": [] } }.to_json)
resp2 = StubResp.new("201", { "data" => { "tags": [] } }.to_json)
params = [ url,
{"tags": ["channel:beta"]}.to_json,
{"Content-Type"=>"application/json"} ]
expect(NervesHub.conn).to(receive(:get).with(url).and_return(resp))
expect(NervesHub.conn).to(receive(:put).with(*params).and_return(resp2))
run_jobs_now do
config.update_attributes!(update_channel: "beta")
end
end
end

View File

@ -119,6 +119,14 @@ def const_reassign(target, const, value)
target.const_set(const, value)
end
class StubResp
attr_accessor :code, :body
def initialize(code, body)
@code, @body = code, body
end
end
class NiceResponse
attr_reader :r, :body