diametric 0.0.4 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +21 -18
  3. data/Jarfile +15 -1
  4. data/README.md +22 -14
  5. data/Rakefile +17 -1
  6. data/bin/datomic-rest +33 -0
  7. data/bin/download-datomic +13 -0
  8. data/datomic_version.yml +4 -0
  9. data/diametric.gemspec +9 -6
  10. data/ext/diametric/DiametricCollection.java +147 -0
  11. data/ext/diametric/DiametricConnection.java +113 -0
  12. data/ext/diametric/DiametricDatabase.java +107 -0
  13. data/ext/diametric/DiametricEntity.java +90 -0
  14. data/ext/diametric/DiametricListenableFuture.java +47 -0
  15. data/ext/diametric/DiametricObject.java +66 -0
  16. data/ext/diametric/DiametricPeer.java +414 -0
  17. data/ext/diametric/DiametricService.java +102 -0
  18. data/ext/diametric/DiametricUUID.java +61 -0
  19. data/ext/diametric/DiametricUtils.java +183 -0
  20. data/lib/boolean_type.rb +3 -0
  21. data/lib/diametric.rb +24 -0
  22. data/lib/diametric/entity.rb +219 -14
  23. data/lib/diametric/generators/active_model.rb +2 -2
  24. data/lib/diametric/persistence.rb +0 -1
  25. data/lib/diametric/persistence/common.rb +28 -9
  26. data/lib/diametric/persistence/peer.rb +122 -87
  27. data/lib/diametric/persistence/rest.rb +4 -3
  28. data/lib/diametric/query.rb +94 -23
  29. data/lib/diametric/rest_service.rb +74 -0
  30. data/lib/diametric/service_base.rb +77 -0
  31. data/lib/diametric/transactor.rb +86 -0
  32. data/lib/diametric/version.rb +1 -1
  33. data/lib/diametric_service.jar +0 -0
  34. data/lib/value_enums.rb +8 -0
  35. data/spec/conf_helper.rb +55 -0
  36. data/spec/config/free-transactor-template.properties +73 -0
  37. data/spec/config/logback.xml +59 -0
  38. data/spec/data/seattle-data0.dtm +452 -0
  39. data/spec/data/seattle-data1.dtm +326 -0
  40. data/spec/developer_create_sample.rb +39 -0
  41. data/spec/developer_query_spec.rb +120 -0
  42. data/spec/diametric/config_spec.rb +1 -1
  43. data/spec/diametric/entity_spec.rb +263 -0
  44. data/spec/diametric/peer_api_spec.rb +147 -0
  45. data/spec/diametric/persistence/peer_many2many_spec.rb +76 -0
  46. data/spec/diametric/persistence/peer_spec.rb +13 -22
  47. data/spec/diametric/persistence/rest_spec.rb +12 -19
  48. data/spec/diametric/query_spec.rb +4 -5
  49. data/spec/diametric/rest_service_spec.rb +56 -0
  50. data/spec/diametric/transactor_spec.rb +68 -0
  51. data/spec/integration_spec.rb +5 -3
  52. data/spec/parent_child_sample.rb +42 -0
  53. data/spec/peer_integration_spec.rb +106 -22
  54. data/spec/peer_seattle_spec.rb +200 -0
  55. data/spec/rc2013_seattle_big.rb +82 -0
  56. data/spec/rc2013_seattle_small.rb +60 -0
  57. data/spec/rc2013_simple_sample.rb +72 -0
  58. data/spec/seattle_integration_spec.rb +106 -0
  59. data/spec/simple_validation_sample.rb +31 -0
  60. data/spec/spec_helper.rb +31 -45
  61. data/spec/support/entities.rb +157 -0
  62. data/spec/support/gen_entity_class.rb +2 -0
  63. data/spec/support/persistence_examples.rb +9 -5
  64. data/spec/test_version_file.yml +4 -0
  65. metadata +131 -75
  66. data/Jarfile.lock +0 -134
  67. data/lib/jrclj.rb +0 -63
@@ -0,0 +1,74 @@
1
+ require 'diametric/service_base'
2
+
3
+ module Diametric
4
+ class RestService
5
+ include ::Diametric::ServiceBase
6
+ class << self
7
+ def datomic_command(datomic_home)
8
+ classpath = datomic_classpath(datomic_home)
9
+ command = ["java -server -Xmx1g", "-cp", classpath, "clojure.main", "-i", "#{datomic_home}/bin/bridge.clj", "--main datomic.rest"].flatten.join(" ")
10
+ end
11
+ end
12
+
13
+ attr_accessor :datomic_version, :datomic_version_no, :datomic_home, :pid
14
+ attr_accessor :host, :port, :db_alias, :uri
15
+
16
+ def initialize(conf="datomic_version.yml", dest="vendor/datomic")
17
+ @conf = conf
18
+ @dest = dest
19
+ @datomic_version = RestService.datomic_version(conf)
20
+ @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, @datomic_version)
21
+ @datomic_version_no = RestService.datomic_version_no(@datomic_version)
22
+ @pid = nil
23
+ end
24
+
25
+ def start(opts={})
26
+ return if @pid
27
+ RestService.download(@conf, @dest)
28
+ command = RestService.datomic_command(@datomic_home)
29
+
30
+ require 'socket'
31
+ @host = opts[:host] ? opts[:host] : Socket.gethostname
32
+ @port = opts[:port] ? opts[:port] : 9000
33
+ @db_alias = opts[:db_alias] ? opts[:db_alias] : "free"
34
+ @uri = opts[:uri] ? opts[:uri] : "datomic:mem://"
35
+
36
+ uri = URI("http://#{@host}:#{@port}/")
37
+
38
+ unless port_available?(uri)
39
+ puts "Somebody is using #{@port}. Choose other."
40
+ return
41
+ end
42
+
43
+ temp_pid = spawn("#{command} -p #{@port} #{@db_alias} #{@uri}")
44
+
45
+ @pid = temp_pid if ready?(uri)
46
+ end
47
+
48
+ def stop
49
+ Process.kill("HUP", @pid) if @pid
50
+ @pid = nil
51
+ end
52
+
53
+ def port_available?(uri)
54
+ response = Net::HTTP.get_response(uri)
55
+ false
56
+ rescue Errno::ECONNREFUSED
57
+ true
58
+ end
59
+
60
+ def ready?(uri)
61
+ while true
62
+ begin
63
+ response = Net::HTTP.get_response(uri)
64
+ return true
65
+ rescue
66
+ sleep 1
67
+ redo
68
+ end
69
+ end
70
+ true
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,77 @@
1
+ require 'net/http'
2
+ require 'pathname'
3
+ require 'yaml'
4
+
5
+ module Diametric
6
+ module ServiceBase
7
+ def self.included(base)
8
+ base.send(:extend, ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def datomic_conf_file?(file="datomic_version.yml")
13
+ if Pathname.new(file).relative?
14
+ file = File.join(File.dirname(__FILE__), "../..", file)
15
+ end
16
+ return File.exists?(file)
17
+ end
18
+
19
+ def datomic_version(conf="datomic_version.yml")
20
+ if datomic_conf_file?(conf)
21
+ datomic_names = File.read(File.join(File.dirname(__FILE__), "../..", conf))
22
+ datomic_versions = YAML.load(datomic_names)
23
+ if ENV['DIAMETRIC_ENV'] && (ENV['DIAMETRIC_ENV'] == "pro")
24
+ datomic_versions["pro"]
25
+ else
26
+ datomic_versions["free"]
27
+ end
28
+ else
29
+ conf
30
+ end
31
+ end
32
+
33
+ def datomic_version_no(datomic_version_str)
34
+ /(\d|\.)+/.match(datomic_version_str)[0]
35
+ end
36
+
37
+ def downloaded?(conf="datomic_version.yml", dest="vendor/datomic")
38
+ datomic_home = datomic_version(conf)
39
+ if Pathname.new(dest).relative?
40
+ dest = File.join(File.dirname(__FILE__), "..", "..", dest)
41
+ end
42
+ File.exists?(File.join(dest, datomic_home))
43
+ end
44
+
45
+ def download(conf="datomic_version.yml", dest="vendor/datomic")
46
+ return true if downloaded?(conf, dest)
47
+ version = datomic_version(conf)
48
+ url = "http://downloads.datomic.com/#{datomic_version_no(version)}/#{version}.zip"
49
+ if Pathname.new(dest).relative?
50
+ dest = File.join(File.dirname(__FILE__), "../..", dest)
51
+ end
52
+ require 'open-uri'
53
+ require 'zip/zipfilesystem'
54
+ open(url) do |zip_file|
55
+ Zip::ZipFile.open(zip_file.path) do |zip_path|
56
+ zip_path.each do |zip_entry|
57
+ file_path = File.join(dest, zip_entry.to_s)
58
+ FileUtils.mkdir_p(File.dirname(file_path))
59
+ zip_path.extract(zip_entry, file_path) { true }
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def datomic_classpath(datomic_home)
66
+ # Find jar archives
67
+ jars = Dir["#{datomic_home}/lib/*.jar"]
68
+ jars += Dir["#{datomic_home}/*transactor*.jar"]
69
+
70
+ # Setup CLASSPATH
71
+ classpath = jars.join(File::PATH_SEPARATOR)
72
+ files = ["samples/clj", "bin", "resources"]
73
+ classpath += File::PATH_SEPARATOR + files.collect {|f| datomic_home + "/" + f}.join(File::PATH_SEPARATOR)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,86 @@
1
+ require 'diametric/service_base'
2
+ require 'pathname'
3
+ require 'securerandom'
4
+
5
+ module Diametric
6
+ class Transactor
7
+ include ::Diametric::ServiceBase
8
+ class << self
9
+ def datomic_command(datomic_home)
10
+ classpath = datomic_classpath(datomic_home)
11
+ java_opts = "-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly"
12
+ command = ["java -server -Xmx1g -Xms1g", java_opts, "-cp", classpath, "clojure.main", "--main datomic.launcher"].flatten.join(" ")
13
+ end
14
+ end
15
+
16
+ attr_accessor :datomic_version, :datomic_version_no, :datomic_home, :pid
17
+ attr_accessor :host, :port, :db_alias, :uri
18
+
19
+ def initialize(conf="datomic_version.yml", dest="vendor/datomic")
20
+ @conf = conf
21
+ @dest = dest
22
+ @datomic_version = Transactor.datomic_version(conf)
23
+ if Pathname.new(dest).relative?
24
+ @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, @datomic_version)
25
+ else
26
+ @datomic_home = File.join(dest, @datomic_version)
27
+ end
28
+ @datomic_version_no = Transactor.datomic_version_no(@datomic_version)
29
+ @hostname = nil
30
+ @port = nil
31
+ @pid = nil
32
+ end
33
+
34
+ def start(props)
35
+ return if @pid
36
+ Transactor.download(@conf, @dest)
37
+ command = Transactor.datomic_command(@datomic_home)
38
+
39
+ unless File.exists?(props)
40
+ puts "Transactor property file #{props} doesn't exist."
41
+ return
42
+ end
43
+ properties(props)
44
+ tmp_pid = spawn("#{command} #{props}")
45
+ if ready?
46
+ @pid = tmp_pid
47
+ end
48
+ @pid
49
+ end
50
+
51
+ def stop
52
+ Process.kill("HUP", @pid) if @pid
53
+ @pid = nil
54
+ end
55
+
56
+ def properties(props)
57
+ File.readlines(props).each do |line|
58
+ m = /^(host=)(.+)/.match(line)
59
+ if m && m[2]
60
+ @hostname = m[2]
61
+ end
62
+ m = /^(port=)(\d+)/.match(line)
63
+ if m && m[2]
64
+ @port = m[2]
65
+ end
66
+ end
67
+ end
68
+
69
+ def ready?
70
+ tmp_database = "datomic:free://#{@hostname}:#{port}/tmp_database-#{SecureRandom.uuid}"
71
+ while true
72
+ begin
73
+ if Diametric::Persistence::Peer.create_database(tmp_database)
74
+ Diametric::Persistence::Peer.delete_database(tmp_database)
75
+ return true
76
+ end
77
+ rescue
78
+ sleep 1
79
+ redo
80
+ end
81
+ end
82
+ true
83
+ end
84
+ end
85
+
86
+ end
@@ -1,3 +1,3 @@
1
1
  module Diametric
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.1"
3
3
  end
Binary file
@@ -0,0 +1,8 @@
1
+ module Kernel
2
+ def enum(syms)
3
+ prefix = self.name.downcase.sub(/::/, ".")
4
+ syms.each do |s|
5
+ const_set(s.to_s.upcase, ":#{prefix}/#{s.to_s.downcase.sub(/_/, "-")}")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ require 'rspec'
2
+ #require 'pry'
3
+
4
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
5
+ require 'lock_jar'
6
+ jar_file = File.join(File.dirname(__FILE__), "..", "Jarfile")
7
+ lock_file = File.join(File.dirname(__FILE__), "..", "Jarfile.lock")
8
+ LockJar.lock(jar_file)
9
+ LockJar.install(lock_file)
10
+ LockJar.load(lock_file)
11
+ end
12
+ require 'diametric'
13
+ #Dir["./spec/support/**/*.rb"].each {|f| require f}
14
+
15
+ RSpec.configure do |c|
16
+ # c.fail_fast = true
17
+
18
+ c.filter_run_excluding :integration => true unless ENV['INTEGRATION']
19
+ c.filter_run_excluding :jruby => (not is_jruby?)
20
+ c.filter_run_excluding :service => true unless ENV['RESTSERVICE']
21
+
22
+ c.filter_run_including :focused => true
23
+ c.alias_example_to :fit, :focused => true
24
+
25
+ c.run_all_when_everything_filtered = true
26
+ c.treat_symbols_as_metadata_keys_with_true_values = true
27
+
28
+ c.before(:suite) do
29
+ #@rest = Diametric::RestService.new("spec/test_version_file.cnf", "tmp/datomic")
30
+ #@rest.start(:port => 46291, :db_alias => @storage, :uri => "datomic:mem://")
31
+ #PID = @rest.pid
32
+ end
33
+
34
+ c.after(:suite) do
35
+ Diametric::Persistence::Peer.shutdown(true) if is_jruby?
36
+ #Process.kill("HUP", PID)
37
+ end
38
+ end
39
+
40
+ shared_examples "ActiveModel" do |model|
41
+ require 'test/unit/assertions'
42
+ require 'active_model/lint'
43
+ include Test::Unit::Assertions
44
+ include ActiveModel::Lint::Tests
45
+
46
+ active_model_lints = ActiveModel::Lint::Tests.public_instance_methods.map(&:to_s).grep(/^test/)
47
+
48
+ let(:model) { subject }
49
+
50
+ active_model_lints.each do |test_name|
51
+ it "#{test_name.sub(/^test_/, '')}" do
52
+ send(test_name)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,73 @@
1
+ ################################################################
2
+ # Basic connection settings.
3
+
4
+ protocol=free
5
+ host=localhost
6
+ port=39082
7
+
8
+
9
+
10
+ ## OPTIONAL ####################################################
11
+ # The dev: and free: protocols typically use three ports
12
+ # starting with the selected :port, but you can specify the
13
+ # other ports explicitly, e.g. for virtualization environs
14
+ # that do not issue contiguous ports.
15
+
16
+ # h2-port=4335
17
+ # h2-web-port=4336
18
+
19
+
20
+
21
+ ################################################################
22
+ # See http://docs.datomic.com/capacity.html
23
+
24
+
25
+ # Recommended settings for -Xmx4g, ongoing usage.
26
+ memory-index-threshold=32m
27
+ memory-index-max=128m
28
+ object-cache-max=1g
29
+
30
+ # Recommended settings for -Xmx4g import jobs.
31
+ # memory-index-threshold=512m
32
+ # memory-index-max=1g
33
+ # object-cache-max=1g
34
+
35
+ # Recommended settings for -Xmx1g usage, e.g. dev laptops.
36
+ # memory-index-threshold=32m
37
+ # memory-index-max=128m
38
+ # object-cache-max=128m
39
+
40
+
41
+
42
+ ## OPTIONAL ####################################################
43
+
44
+
45
+ # Set to false to disable SSL between the peers and the transactor.
46
+ # Default: true
47
+ # encrypt-channel=true
48
+
49
+ # Data directory is used for dev: and free: storage, and
50
+ # as a temporary directory for all storages.
51
+ data-dir=tmp/data
52
+
53
+ # Transactor will log here, see bin/logback.xml to configure logging.
54
+ log-dir=tmp/log
55
+
56
+ # Transactor will write process pid here on startup
57
+ pid-file=tmp/transactor.pid
58
+
59
+
60
+
61
+ ## OPTIONAL ####################################################
62
+ # See http://docs.datomic.com/capacity.html
63
+
64
+
65
+ # Soft limit on the number of concurrent writes to storage.
66
+ # Default: 4, Miniumum: 2
67
+ # write-concurrency=4
68
+
69
+ # Soft limit on the number of concurrent reads to storage.
70
+ # Default: 2 times write-concurrency, Miniumum: 2
71
+ # read-concurrency=8
72
+
73
+
@@ -0,0 +1,59 @@
1
+ <configuration>
2
+
3
+ <!-- prevent per-message overhead for jul logging calls, e.g. Hornet -->
4
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
5
+ <resetJUL>true</resetJUL>
6
+ </contextListener>
7
+
8
+ <appender name="MAIN" class="ch.qos.logback.core.rolling.RollingFileAppender">
9
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
10
+ <fileNamePattern>${DATOMIC_LOG_DIR:-log}/%d{yyyy-MM-dd}.log</fileNamePattern>
11
+ <maxHistory>72</maxHistory>
12
+ </rollingPolicy>
13
+ <prudent>true</prudent> <!-- multi jvm safe, slower -->
14
+ <encoder>
15
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-10contextName %logger{36} - %msg%n</pattern>
16
+ </encoder>
17
+ </appender>
18
+
19
+ <!-- uncomment to log storage access -->
20
+ <!-- <logger name="datomic.kv-cluster" level="DEBUG"/> -->
21
+
22
+ <!-- uncomment to log transactor heartbeat -->
23
+ <!-- <logger name="datomic.lifecycle" level="DEBUG"/> -->
24
+
25
+ <!-- uncomment to log transactions (transactor side) -->
26
+ <!-- <logger name="datomic.transaction" level="DEBUG"/> -->
27
+
28
+ <!-- uncomment to log transactions (peer side) -->
29
+ <!-- <logger name="datomic.peer" level="DEBUG"/> -->
30
+
31
+ <!-- uncomment to log the transactor log -->
32
+ <!-- <logger name="datomic.log" level="DEBUG"/> -->
33
+
34
+ <!-- uncomment to log peer connection to transactor -->
35
+ <!-- <logger name="datomic.connector" level="DEBUG"/> -->
36
+
37
+ <!-- uncomment to log storage gc -->
38
+ <!-- <logger name="datomic.garbage" level="DEBUG"/> -->
39
+
40
+ <!-- these namespsaces create a ton of log noise -->
41
+ <logger name="httpclient" level="INFO"/>
42
+ <logger name="org.apache.commons.httpclient" level="INFO"/>
43
+ <logger name="org.apache.http" level="INFO"/>
44
+ <logger name="org.jets3t" level="INFO"/>
45
+ <logger name="com.amazonaws" level="INFO"/>
46
+ <logger name="com.amazonaws.request" level="WARN"/>
47
+ <logger name="sun.rmi" level="INFO"/>
48
+ <logger name="net.spy.memcached" level="INFO"/>
49
+ <logger name="com.couchbase.client" level="INFO"/>
50
+ <logger name="org.apache.zookeeper" level="INFO"/>
51
+ <logger name="com.ning.http.client.providers.netty" level="INFO"/>
52
+ <logger name="org.eclipse.jetty" level="INFO"/>
53
+ <logger name="org.hornetq.core.client.impl" level="INFO"/>
54
+ <logger name="org.apache.tomcat.jdbc.pool" level="INFO"/>
55
+
56
+ <root level="info">
57
+ <appender-ref ref="MAIN"/>
58
+ </root>
59
+ </configuration>