ims_caliper 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +16 -0
- data/README.md +16 -0
- data/caliper.gemspec +26 -0
- data/config/locales/en.yml +86 -0
- data/lib/caliper/client.rb +33 -0
- data/lib/caliper/consumer/base.rb +46 -0
- data/lib/caliper/consumer/queue.rb +40 -0
- data/lib/caliper/consumer/socket.rb +132 -0
- data/lib/caliper/defaults.rb +8 -0
- data/lib/caliper/entities/annotation/annotation.rb +29 -0
- data/lib/caliper/entities/annotation/bookmark_annotation.rb +17 -0
- data/lib/caliper/entities/annotation/highlight_annotation.rb +18 -0
- data/lib/caliper/entities/annotation/shared_annotation.rb +18 -0
- data/lib/caliper/entities/annotation/tag_annotation.rb +17 -0
- data/lib/caliper/entities/annotation/text_position_selector.rb +14 -0
- data/lib/caliper/entities/digital_resource.rb +52 -0
- data/lib/caliper/entities/entity.rb +44 -0
- data/lib/caliper/entities/foaf/agent.rb +12 -0
- data/lib/caliper/entities/generatable.rb +9 -0
- data/lib/caliper/entities/learning_context.rb +21 -0
- data/lib/caliper/entities/lis/course_section.rb +18 -0
- data/lib/caliper/entities/lis/organization.rb +22 -0
- data/lib/caliper/entities/lis/person.rb +12 -0
- data/lib/caliper/entities/outcome/result.rb +23 -0
- data/lib/caliper/entities/reading/epub_chapter.rb +20 -0
- data/lib/caliper/entities/reading/epub_part.rb +20 -0
- data/lib/caliper/entities/reading/epub_sub_chapter.rb +20 -0
- data/lib/caliper/entities/reading/epub_volume.rb +20 -0
- data/lib/caliper/entities/reading/frame.rb +32 -0
- data/lib/caliper/entities/schemadotorg/audio_object.rb +15 -0
- data/lib/caliper/entities/schemadotorg/creative_work.rb +12 -0
- data/lib/caliper/entities/schemadotorg/image_object.rb +15 -0
- data/lib/caliper/entities/schemadotorg/media_object.rb +19 -0
- data/lib/caliper/entities/schemadotorg/software_application.rb +11 -0
- data/lib/caliper/entities/schemadotorg/thing.rb +9 -0
- data/lib/caliper/entities/schemadotorg/video_object.rb +15 -0
- data/lib/caliper/entities/schemadotorg/web_page.rb +11 -0
- data/lib/caliper/entities/session.rb +26 -0
- data/lib/caliper/entities/software_application.rb +19 -0
- data/lib/caliper/entities/targetable.rb +12 -0
- data/lib/caliper/entities/web_page.rb +13 -0
- data/lib/caliper/event/.shared.rb.swp +0 -0
- data/lib/caliper/event/annotation_event.rb +14 -0
- data/lib/caliper/event/event.rb +68 -0
- data/lib/caliper/event/media_event.rb +19 -0
- data/lib/caliper/event/navigation_event.rb +23 -0
- data/lib/caliper/event/outcome_event.rb +20 -0
- data/lib/caliper/event/session_event.rb +21 -0
- data/lib/caliper/event/view_event.rb +20 -0
- data/lib/caliper/options.rb +18 -0
- data/lib/caliper/profiles/annotation_profile.rb +61 -0
- data/lib/caliper/profiles/profile.rb +46 -0
- data/lib/caliper/profiles/reading_profile.rb +36 -0
- data/lib/caliper/profiles/session_profile.rb +29 -0
- data/lib/caliper/request/event_store_envelope.rb +9 -0
- data/lib/caliper/request/event_store_requestor.rb +41 -0
- data/lib/caliper/request/http_requestor.rb +42 -0
- data/lib/caliper/sensor.rb +37 -0
- data/lib/caliper/stats/atomic_wrapper.rb +86 -0
- data/lib/caliper/stats/statistic.rb +104 -0
- data/lib/caliper/stats/statistics.rb +45 -0
- data/lib/caliper/stats/statistics_map.rb +39 -0
- data/lib/caliper/validators/error_message.rb +43 -0
- data/lib/caliper/validators/event_validator.rb +37 -0
- data/lib/caliper/validators/event_validator_context.rb +16 -0
- data/lib/caliper/validators/property_type_check.rb +14 -0
- data/lib/caliper/validators/session_login_event_validator.rb +103 -0
- data/lib/caliper/validators/session_logout_event_validator.rb +102 -0
- data/lib/caliper/validators/time_check.rb +30 -0
- data/lib/caliper/version.rb +4 -0
- data/lib/caliper.rb +17 -0
- data/spec/lib/client_spec.rb +35 -0
- data/spec/lib/consumer/base_spec.rb +28 -0
- data/spec/lib/consumer/queue_spec.rb +16 -0
- data/spec/lib/event/annotation_spec.rb +12 -0
- data/spec/lib/event/bookmarked_spec.rb +17 -0
- data/spec/lib/event/commented_spec.rb +19 -0
- data/spec/lib/event/highlighted_spec.rb +18 -0
- data/spec/lib/event/navigation_spec.rb +15 -0
- data/spec/lib/event/shared_spec.rb +18 -0
- data/spec/lib/event/tagged_spec.rb +17 -0
- data/spec/lib/event/used_spec.rb +15 -0
- data/spec/lib/event/viewed_spec.rb +15 -0
- data/spec/spec_helper.rb +26 -0
- data/test/caliper/events/session_login_event_test.rb +58 -0
- data/test/caliper/events/session_logout_event_test.rb +55 -0
- data/test/caliper/events/session_timeout_event_test.rb +55 -0
- data/test/caliper/request/http_requestor_test.rb +59 -0
- data/test/caliper/test_event.rb +53 -0
- data/test/caliper/test_utils.rb +198 -0
- data/test/fixtures/caliper_session_login_event.json +71 -0
- data/test/fixtures/caliper_session_logout_event.json +52 -0
- data/test/fixtures/caliper_session_timeout_event.json +52 -0
- data/test/fixtures/event_store_payload.json +85 -0
- metadata +165 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
require_relative './profile'
|
3
|
+
require_relative '../entities/digital_resource'
|
4
|
+
require_relative '../entities/annotation/annotation'
|
5
|
+
require_relative '../entities/reading/frame'
|
6
|
+
|
7
|
+
module Caliper
|
8
|
+
module Profiles
|
9
|
+
module AnnotationActions
|
10
|
+
ATTACHED = "annotation.attached"
|
11
|
+
BOOKMARKED = "annotation.bookmarked"
|
12
|
+
CLASSIFIED = "annotation.classified"
|
13
|
+
COMMENTED = "annotation.commented"
|
14
|
+
DESCRIBED = "annotation.described"
|
15
|
+
HIGHLIGHTED = "annotation.highlighted"
|
16
|
+
IDENTIFIED = "annotation.identified"
|
17
|
+
LIKED = "annotation.liked"
|
18
|
+
LINKED = "annotation.linked"
|
19
|
+
RANKED = "annotation.ranked"
|
20
|
+
QUESTIONED = "annotation.questioned"
|
21
|
+
RECOMMENDED = "annotation.recommended"
|
22
|
+
REPLIED = "annotation.replied"
|
23
|
+
SHARED = "annotation.shared"
|
24
|
+
SUBSCRIBED = "annotation.subscribed"
|
25
|
+
TAGGED = "annotation.tagged"
|
26
|
+
end
|
27
|
+
class ReadingProfile < Profile
|
28
|
+
include AnnotationActions
|
29
|
+
attr_accessor :key, # String
|
30
|
+
:lookup # hash of ReadingActions
|
31
|
+
|
32
|
+
# whether object if of type DigitalResource
|
33
|
+
def validate_object (object)
|
34
|
+
if (object.is_a? AnnotationType::BOOKMARK_ANNOTATION)
|
35
|
+
## TODO check required properties
|
36
|
+
return object
|
37
|
+
elsif (object.is_a? AnnotationType::HIGHLIGHT_ANNOTATION)
|
38
|
+
## TODO check required properties
|
39
|
+
return object
|
40
|
+
elsif (object.is_a? AnnotationType::SHARED_ANNOTATION)
|
41
|
+
## TODO check required properties
|
42
|
+
return object
|
43
|
+
elsif (object.is_a? AnnotationType::TAG_ANNOTATION)
|
44
|
+
## TODO check required properties
|
45
|
+
return object
|
46
|
+
else
|
47
|
+
fail "Object must be of type Annotation"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# whether target is of type Frame
|
52
|
+
def validate_target(target)
|
53
|
+
if (target is_a? Frame)
|
54
|
+
return target
|
55
|
+
else
|
56
|
+
fail "Target must be of type Frame."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require 'i18n'
|
3
|
+
|
4
|
+
module Caliper
|
5
|
+
module Profiles
|
6
|
+
module ProfileActions
|
7
|
+
DOWNLOADED = "item.downloaded"
|
8
|
+
UPLOADED = "item.uploaded"
|
9
|
+
LOGGED_IN = "session.loggedIn"
|
10
|
+
LOGGED_OUT = "session.loggedOut"
|
11
|
+
NAVIGATED_TO = "navigation.navigatedTo"
|
12
|
+
end
|
13
|
+
|
14
|
+
module ProfileConformance
|
15
|
+
ACTION_IS_NULL = "an action must be specified."
|
16
|
+
ACTION_UNRECOGNIZED = "unrecognized action."
|
17
|
+
ACTOR_NOT_PERSON = "actor must be of type Person"
|
18
|
+
ACTOR_NOT_SOFTWAREAPP = "actor must be of type SoftwareApplication"
|
19
|
+
CONTEXT_ERROR = "context URI must be specified"
|
20
|
+
DURATION_INVALID = "duration format is invalid"
|
21
|
+
ENDEDATTIME_SET = "endedAtTime must not be specified"
|
22
|
+
EVENT_ILLEGAL_STATE = "event constructed in an illegal state."
|
23
|
+
GENERATED_NOT_NULL = "a generated object is not required."
|
24
|
+
GENERATED_NOT_SESSION = "generated object must be of type Session"
|
25
|
+
OBJECT_NOT_SOFTWAREAPP = "object must be of type SoftwareApplication"
|
26
|
+
STARTEDATTIME_IS_NULL = "startedAtTime must be specified."
|
27
|
+
TARGET_NOT_DIGITALRESOURCE = "target must be of type DigitalResource"
|
28
|
+
TARGET_NOT_SESSION = "target must be of type Session"
|
29
|
+
TIME_ERROR = "end time must be greater than start time."
|
30
|
+
TYPE_ERROR = "type URI must be specified"
|
31
|
+
end
|
32
|
+
|
33
|
+
class Profile
|
34
|
+
include ProfileActions
|
35
|
+
|
36
|
+
def initialize()
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_navigated_to_action_from_bundle(key)
|
40
|
+
if key.equal? ProfileActions::NAVIGATED_TO
|
41
|
+
return I18n.translate :action
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
require_relative './profile'
|
3
|
+
require_relative '../entities/digital_resource'
|
4
|
+
require_relative '../entities/reading/frame'
|
5
|
+
|
6
|
+
module Caliper
|
7
|
+
module Profiles
|
8
|
+
module ReadingActions
|
9
|
+
SEARCHED = "reading.searched"
|
10
|
+
VIEWED = "reading.viewed"
|
11
|
+
end
|
12
|
+
class ReadingProfile < Caliper::Profiles::Profile
|
13
|
+
|
14
|
+
attr_accessor :key, # String
|
15
|
+
:lookup # hash of ReadingActions
|
16
|
+
|
17
|
+
# whether object if of type DigitalResource
|
18
|
+
def validate_object(object)
|
19
|
+
if (object.is_a? DigitalResource)
|
20
|
+
return object
|
21
|
+
else
|
22
|
+
fail "Object must e of type DigitalResource"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# whether target is of type Frame
|
27
|
+
def validate_target(target)
|
28
|
+
if (target is_a? frame)
|
29
|
+
return target
|
30
|
+
else
|
31
|
+
fail "Target must be of type Frame."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require_relative './profile'
|
3
|
+
require_relative '../entities/digital_resource'
|
4
|
+
require_relative '../entities/annotation/annotation'
|
5
|
+
require_relative '../entities/reading/frame'
|
6
|
+
|
7
|
+
module Caliper
|
8
|
+
module Profiles
|
9
|
+
module SessionActions
|
10
|
+
LOGGED_IN = "session.loggedIn"
|
11
|
+
LOGGED_OUT = "session.loggedOut"
|
12
|
+
TIMEOUT = "session.timeOut"
|
13
|
+
UNRECOGNIZED = "action.unrecognized"
|
14
|
+
end
|
15
|
+
class SessionProfile < Profile
|
16
|
+
include SessionActions
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
# whether object if of type DigitalResource
|
23
|
+
def validate_event (event)
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'event_store_envelope'
|
3
|
+
|
4
|
+
module Caliper
|
5
|
+
module Request
|
6
|
+
class EventStoreRequestor
|
7
|
+
|
8
|
+
|
9
|
+
def get_payload_json(caliper_event, id, send_time)
|
10
|
+
|
11
|
+
list_payload = Array.new
|
12
|
+
|
13
|
+
# new event envelope
|
14
|
+
envelope = EventStoreEnvelope.new
|
15
|
+
envelope.id = id
|
16
|
+
envelope.type = "caliperEvent"
|
17
|
+
envelope.time = send_time.to_s
|
18
|
+
envelope.data = caliper_event
|
19
|
+
|
20
|
+
# add envelope into array
|
21
|
+
list_payload<< envelope
|
22
|
+
|
23
|
+
json_payload = JSON.generate(list_payload)
|
24
|
+
return json_payload
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_payload(caliper_event, id, send_time)
|
28
|
+
if (id.nil?)
|
29
|
+
id = "caliper-java_" + SecureRandom.uuid
|
30
|
+
end
|
31
|
+
|
32
|
+
if (send_time.nil?)
|
33
|
+
send_time = Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
json_payload = get_payload_json(caliper_event, id, send_time)
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative 'event_store_requestor'
|
2
|
+
require_relative 'event_store_envelope'
|
3
|
+
require "net/http"
|
4
|
+
require "uri"
|
5
|
+
|
6
|
+
module Caliper
|
7
|
+
module Request
|
8
|
+
class HttpRequestor < Caliper::Request::EventStoreRequestor
|
9
|
+
|
10
|
+
attr_accessor :options
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def send(event)
|
17
|
+
status = false
|
18
|
+
|
19
|
+
# the option.host returns whole url string
|
20
|
+
uri = URI(@options.host)
|
21
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
22
|
+
request = Net::HTTP::Post.new uri
|
23
|
+
|
24
|
+
response = http.request request # Net::HTTPResponse object
|
25
|
+
end
|
26
|
+
|
27
|
+
if (response.code != 200)
|
28
|
+
status_code = response.code
|
29
|
+
|
30
|
+
# failed call
|
31
|
+
status = false
|
32
|
+
fail "Failed: HTTP error code: " + status_code
|
33
|
+
else
|
34
|
+
# success call
|
35
|
+
status = true
|
36
|
+
end
|
37
|
+
|
38
|
+
return status
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative "client"
|
2
|
+
|
3
|
+
## create
|
4
|
+
module Caliper
|
5
|
+
class Sensor
|
6
|
+
attr_accessor :default_client
|
7
|
+
|
8
|
+
# options to configure the behavior of Caliper client
|
9
|
+
def initialize(options)
|
10
|
+
@default_client=Client.new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Client initialization check
|
14
|
+
def is_initialized()
|
15
|
+
if default_client.nil?
|
16
|
+
# fail with RuntimeError
|
17
|
+
fail 'Caliper client is not initialized. Please call Caliper.initialize(..); before calling measure or describe'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Describe a Entity that is part of the learning graph
|
22
|
+
def describe(entity)
|
23
|
+
is_initialized()
|
24
|
+
@default_client.describe(entity)
|
25
|
+
end
|
26
|
+
|
27
|
+
def send(event)
|
28
|
+
is_initialized()
|
29
|
+
@default_client.describe(event)
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_statistics()
|
33
|
+
is_initialized()
|
34
|
+
@default_client.getStatistics()
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'atomic'
|
2
|
+
|
3
|
+
# extends the atomic class with several new functions
|
4
|
+
module Caliper
|
5
|
+
module Stats
|
6
|
+
class AtomicWrapper < Atomic
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(value)
|
10
|
+
super.initialize(value)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Atomically sets to the given value and returns the old value.
|
14
|
+
def get_and_set(new_value)
|
15
|
+
current = @value
|
16
|
+
if (compare_and_set(current, new_value))
|
17
|
+
current
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Atomically increments by one and returns the old value.
|
22
|
+
def get_and_increment()
|
23
|
+
current = @value
|
24
|
+
new_value = current + 1
|
25
|
+
if (compare_and_set(current, new_value))
|
26
|
+
current
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Atomically decrements by one and returns the old value.
|
31
|
+
def get_and_decrement()
|
32
|
+
current = @value
|
33
|
+
new_value = current - 1
|
34
|
+
if (compare_and_set(current, new_value))
|
35
|
+
current
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Atomically adds the given value to the current value
|
40
|
+
# Return the old value
|
41
|
+
def get_and_add(delta)
|
42
|
+
current = @value
|
43
|
+
new_value = current + delta
|
44
|
+
if (compare_and_set(current, new_value))
|
45
|
+
current
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Atomically increments by one the current value.
|
50
|
+
# Return the updated value
|
51
|
+
def increment_and_get()
|
52
|
+
current = @value
|
53
|
+
new_value = current + 1
|
54
|
+
if (compare_and_set(current, new_value))
|
55
|
+
new_value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Atomically decrements by one the current value.
|
60
|
+
# Return the updated value
|
61
|
+
def decrement_and_get()
|
62
|
+
current = @value
|
63
|
+
new_value = current - 1
|
64
|
+
if (compare_and_set(current, new_value))
|
65
|
+
new_value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Atomically adds the given value to the current value.
|
70
|
+
# Return the updated value
|
71
|
+
def add_and_get(delta)
|
72
|
+
current = @value
|
73
|
+
new_value = current + delta
|
74
|
+
if (compare_and_set(current, new_value))
|
75
|
+
new_value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the String representation of the current value.
|
80
|
+
def to_string()
|
81
|
+
return @value.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'atomic'
|
2
|
+
require 'math'
|
3
|
+
|
4
|
+
module Caliper
|
5
|
+
module Stats
|
6
|
+
class Statistic
|
7
|
+
|
8
|
+
attr_accessor :sum, :count, :last
|
9
|
+
|
10
|
+
attr_reader :oldM, :newM, :oldS, :newS
|
11
|
+
|
12
|
+
attr_reader :min, :max
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@sum = AtomicWrapper.new(0)
|
16
|
+
@count = AtomicWrapper.new(0)
|
17
|
+
@last = AtomicWrapper.new(0)
|
18
|
+
@lock = AtomicWrapper.new(false)
|
19
|
+
|
20
|
+
@min = 0
|
21
|
+
@max = 0
|
22
|
+
|
23
|
+
@oldM = 0
|
24
|
+
@newM = 0
|
25
|
+
@oldS = 0
|
26
|
+
@newS = 0
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# add another value to this statistic
|
31
|
+
def update(val)
|
32
|
+
n = @count.add_and_get(1)
|
33
|
+
if (@lock.compare_and_set(false, true))
|
34
|
+
if (n == 1)
|
35
|
+
# this is the first time we are executing, so clear the numbers
|
36
|
+
@oldM = @newM = val
|
37
|
+
@oldS = 0
|
38
|
+
@min = val
|
39
|
+
@max = val
|
40
|
+
else
|
41
|
+
# this is not our first update
|
42
|
+
@newM = @oldM + (val - @oldM) / n
|
43
|
+
@newS = @oldS + (val - @oldM) * (val * @newM)
|
44
|
+
|
45
|
+
@oldM = @newM
|
46
|
+
@oldS = @newS
|
47
|
+
end
|
48
|
+
|
49
|
+
if (@val < @min)
|
50
|
+
@min = val
|
51
|
+
end
|
52
|
+
|
53
|
+
if (@val > @max)
|
54
|
+
@max = val
|
55
|
+
end
|
56
|
+
|
57
|
+
@lock.set(false)
|
58
|
+
end
|
59
|
+
|
60
|
+
@sum.add_and_get(val)
|
61
|
+
@last.set(val)
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear
|
65
|
+
@count.set(0)
|
66
|
+
@sum.set(0.0)
|
67
|
+
@last.set(0.0)
|
68
|
+
|
69
|
+
@lock.set(false)
|
70
|
+
@min = 0
|
71
|
+
@max = 0
|
72
|
+
|
73
|
+
@oldM = 0
|
74
|
+
@newM = 0
|
75
|
+
@oldS = 0
|
76
|
+
@newS = 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_average
|
80
|
+
return count.get() > 0 ? (sum.get() / count.get()) : 0.0
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get the variance
|
84
|
+
def get_variance
|
85
|
+
return (count.get() > 1) ? newS / (count.get() - 1) : 1.0
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get the standard deviation of the stream of values
|
89
|
+
def get_standard_deviation
|
90
|
+
Math.sqrt(get_variance())
|
91
|
+
end
|
92
|
+
|
93
|
+
# Return nicely formatted String for all values
|
94
|
+
def to_s
|
95
|
+
if (@min == 1.0 && @max == 1.0)
|
96
|
+
# this is just a count
|
97
|
+
return "" + get_count();
|
98
|
+
else
|
99
|
+
return "[Count : %d], [Min : %s], [Max : %s], [Average : %s], [Std. Dev. : %s]",@count, @min, @max, getAverage(), getStandardDeviation()
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Caliper
|
2
|
+
module Stats
|
3
|
+
class Statistics < StatisticsMap
|
4
|
+
MEASURE_KEY = "Measure"
|
5
|
+
DESCRIBE_KEY = "Describe"
|
6
|
+
SUCCESSFUL_KEY = "Successful"
|
7
|
+
FAILED_KEY = "Failed"
|
8
|
+
|
9
|
+
# Returns the statistic representing how many describe calls happened
|
10
|
+
def get_describes
|
11
|
+
return ensure(DESCRIBE_KEY)
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_describes(val)
|
15
|
+
update(DESCRIBE_KEY, val)
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_measures
|
19
|
+
return ensure(MEASURE_KEY)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_measures(val)
|
23
|
+
update(MEASURE_KEY, val)
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_successful
|
27
|
+
return ensure(SUCCESSFUL_KEY)
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_successful
|
31
|
+
update(SUCCESSFUL_KEY, val)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_failed
|
35
|
+
return ensure(FAILED_KEY)
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_failed
|
39
|
+
update(FAILED_KEY, val)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Caliper
|
2
|
+
module Stats
|
3
|
+
class StatisticsMap < Hash
|
4
|
+
|
5
|
+
# Make sure the key value exists in the hashmap
|
6
|
+
# Add the key value if not found before
|
7
|
+
def ensure(key)
|
8
|
+
# returns key-ed vale if key exists
|
9
|
+
if has_key?(key)
|
10
|
+
return fetch(key)
|
11
|
+
end
|
12
|
+
|
13
|
+
# else insert the key
|
14
|
+
statistic = Statistic.new()
|
15
|
+
this.put(key, statistic)
|
16
|
+
return statistic
|
17
|
+
end
|
18
|
+
|
19
|
+
# Insert a new Statistic object if there is no key with specified value
|
20
|
+
# Otherwise, update the hashed value with the value provided
|
21
|
+
def update(operation, val)
|
22
|
+
if (!has_key?(operation))
|
23
|
+
this.put(operation, Statistic.new())
|
24
|
+
end
|
25
|
+
this.fetch(operation).update(val)
|
26
|
+
end
|
27
|
+
|
28
|
+
# the pretty formatted string output
|
29
|
+
def to_s
|
30
|
+
r_string = "\r-------- Caliper Java Statistics --------\r";
|
31
|
+
hash.each do |key, value|
|
32
|
+
statistics = value;
|
33
|
+
r_string = r_string + "%s : %s\r", key, statistic.to_s()
|
34
|
+
end
|
35
|
+
return r_string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Caliper
|
2
|
+
module Validators
|
3
|
+
class ErrorMessage
|
4
|
+
|
5
|
+
attr_accessor :text
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@text = ""
|
9
|
+
end
|
10
|
+
|
11
|
+
# append comma if appropriate when building conformance violation message
|
12
|
+
def append_text(text)
|
13
|
+
if (@text.length == 0)
|
14
|
+
# assign text value
|
15
|
+
@text = text
|
16
|
+
else
|
17
|
+
# append text value
|
18
|
+
@text = @text + ",\n" + text + "\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# prepend text
|
23
|
+
# typically a Caliper conformance clause that prefixes a string of one or more violations.
|
24
|
+
def prepend_text(text)
|
25
|
+
@text = text + "\n" + @text
|
26
|
+
end
|
27
|
+
|
28
|
+
# append period and end sentence
|
29
|
+
def end_sentence
|
30
|
+
@text = @text + "."
|
31
|
+
end
|
32
|
+
|
33
|
+
def end_message(text)
|
34
|
+
prepend_text(text)
|
35
|
+
end_sentence
|
36
|
+
end
|
37
|
+
|
38
|
+
def length
|
39
|
+
return @text.length
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Caliper
|
2
|
+
module Validators
|
3
|
+
module EventValidator
|
4
|
+
module Conformance
|
5
|
+
ACTION_IS_NULL = "an action must be specified."
|
6
|
+
ACTION_UNRECOGNIZED = "unrecognized action."
|
7
|
+
ACTOR_NOT_PERSON = "actor must be of type Person"
|
8
|
+
ACTOR_NOT_SOFTWAREAPP = "actor must be of type SoftwareApplication"
|
9
|
+
ASSIGNABLE_NOT_ASSESSMENT = "assignable must be of type Assessment"
|
10
|
+
CONTEXT_ERROR = "context URI must be specified"
|
11
|
+
COUNT_NOT_ZERO = "count must be specified"
|
12
|
+
DURATION_INVALID = "duration format is invalid"
|
13
|
+
ENDEDATTIME_IS_NULL = "endedAtTime must be specified"
|
14
|
+
ENDEDATTIME_SET = "endedAtTime must not be specified"
|
15
|
+
EVENT_ILLEGAL_STATE = "event constructed in an illegal state."
|
16
|
+
GENERATED_NOT_ATTEMPT = "generated object must be of type Attempt"
|
17
|
+
GENERATED_NOT_NULL = "a generated object is not required"
|
18
|
+
GENERATED_NOT_SESSION = "generated object must be of type Session"
|
19
|
+
OBJECT_NOT_ASSESSMENT = "object must be of type Assessment"
|
20
|
+
OBJECT_NOT_SOFTWAREAPP = "object must be of type SoftwareApplication"
|
21
|
+
STARTEDATTIME_IS_NULL = "startedAtTime must be specified"
|
22
|
+
TARGET_NOT_CREATIVEWORK = "target must be of type CreativeWork"
|
23
|
+
TARGET_NOT_DIGITALRESOURCE = "target must be of type DigitalResource"
|
24
|
+
TARGET_NOT_NULL = "target is not required."
|
25
|
+
TARGET_NOT_SESSION = "target must be of type Session"
|
26
|
+
TARGET_NOT_SET = "target must be specified"
|
27
|
+
TARGET_NOT_THING = "target must be of type Thing"
|
28
|
+
TIME_ERROR = "end time must be greater than start time."
|
29
|
+
TYPE_ERROR = "type URI must be specified"
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate
|
33
|
+
# to be implemented
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Caliper
|
2
|
+
module Validators
|
3
|
+
class EventValidatorContext
|
4
|
+
attr_accessor :validator
|
5
|
+
|
6
|
+
def initialize(validator)
|
7
|
+
@validator = validator
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate (event)
|
11
|
+
# do the validation
|
12
|
+
return @validator.validate(event)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
require_relative '../entities/lis/person'
|
3
|
+
require_relative '../entities/schemadotorg/software_application'
|
4
|
+
module Caliper
|
5
|
+
module Validators
|
6
|
+
class PropertyTypeCheck
|
7
|
+
|
8
|
+
# whether the object is of wanted target class
|
9
|
+
def is_object_of_type(object, targetClass)
|
10
|
+
return !object.nil? && object.is_a?(targetClass)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|