diff --git a/.github/workflows/client_ft.yml b/.github/workflows/client_ft.yml index b854961e..882b1508 100644 --- a/.github/workflows/client_ft.yml +++ b/.github/workflows/client_ft.yml @@ -25,7 +25,7 @@ jobs: - name: Get code uses: actions/checkout@v3.5.2 - name: Install golang - uses: actions/setup-go@v4.0.0 + uses: actions/setup-go@v4.0.1 with: go-version: "${{ matrix.go_version }}" - name: Install Build dependencies diff --git a/.github/workflows/juno_server_bin_build.yml b/.github/workflows/juno_server_bin_build.yml index a22451a9..eb43160a 100644 --- a/.github/workflows/juno_server_bin_build.yml +++ b/.github/workflows/juno_server_bin_build.yml @@ -25,7 +25,7 @@ jobs: - name: Get code uses: actions/checkout@v3.5.2 - name: Install golang - uses: actions/setup-go@v4.0.0 + uses: actions/setup-go@v4.0.1 with: go-version: "${{ matrix.go_version }}" - name: Install Build dependencies diff --git a/.github/workflows/juno_server_docker_build.yml b/.github/workflows/juno_server_docker_build.yml index 560a654f..a6236891 100644 --- a/.github/workflows/juno_server_docker_build.yml +++ b/.github/workflows/juno_server_docker_build.yml @@ -18,6 +18,7 @@ jobs: build-juno-docker: strategy: matrix: + # os: [ubuntu-latest, macos-latest] os: [ubuntu-latest] runs-on: ${{ matrix.os }} env: @@ -28,14 +29,21 @@ jobs: steps: - name: Get code uses: actions/checkout@v3.5.2 - - name: Install dependencies + - name: Check openssl version dependencies run: | - sudo apt install openssl -y echo "Openssl Version:" `openssl version` + - name: Set up Docker + # uses: docker-practice/actions-setup-docker@master + # uses: crazy-max/ghaction-setup-docker@v2 + if: ${{ matrix.os == 'macos-latest' }} + run: | + brew install docker + colima start + # For testcontainers to find the Colima socket + # https://github.com/abiosoft/colima/blob/main/docs/FAQ.md#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running + sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock - name: Docker Version Check run: docker version - # - name: Expose GitHub Runtime - # uses: crazy-max/ghaction-github-runtime@v2 - name: Build docker containers run: docker/build.sh - name: Start juno containers diff --git a/README.md b/README.md index 98f10fde..caffd5e6 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ Continue building JunoDB server with +**Note** : +Docker build supported platforms +- Linux (Ubuntu) +- OS X (macOS) ###

Install Dependencies

[Install Docker Engine version 20.10.0+](https://docs.docker.com/engine/install/ubuntu/) Check for existing docker version @@ -207,6 +211,10 @@ More about junoload [here](docs/junoload.md) ## Manual Build +**Note** : +Manual build supported platforms +- Linux (Ubuntu 20.04) + The following sections explain the process for manually building the JunoDB server without Docker. These instructions are based on an Ubuntu 20.04.5 system * [Manual](#manual-build) * [Install Dependencies](#manual_install_dependencies) diff --git a/binary_build/build.sh b/binary_build/build.sh index 87f2b489..072c2ef6 100755 --- a/binary_build/build.sh +++ b/binary_build/build.sh @@ -97,16 +97,16 @@ export CGO_LDFLAGS="-L$rocksdb_dir/lib -L/usr/local/lib -lrocksdb -lstdc++ -lm - juno_version_info="-X juno/pkg/version.BuildTime=$build_time -X juno/pkg/version.Revision=$code_revision -X juno/pkg/version.BuildId=$JUNO_BUILD_NUMBER" juno_executables="\ - juno/cmd/proxy \ - juno/cmd/storageserv \ - juno/cmd/storageserv/storage/db/dbcopy \ - juno/cmd/tools/junocli \ - juno/cmd/clustermgr \ - juno/cmd/dbscanserv \ - juno/cmd/dbscanserv/junoctl \ - juno/test/drv/junoload \ - juno/cmd/tools/junostats\ - juno/cmd/tools/junocfg\ + github.com/paypal/junodb/cmd/proxy \ + github.com/paypal/junodb/cmd/storageserv \ + github.com/paypal/junodb/cmd/storageserv/storage/db/dbcopy \ + github.com/paypal/junodb/cmd/tools/junocli \ + github.com/paypal/junodb/cmd/clustermgr \ + github.com/paypal/junodb/cmd/dbscanserv \ + github.com/paypal/junodb/cmd/dbscanserv/junoctl \ + github.com/paypal/junodb/test/drv/junoload \ + github.com/paypal/junodb/cmd/tools/junostats\ + github.com/paypal/junodb/cmd/tools/junocfg\ " # DO NOT include junoload in any package diff --git a/client/Java/Juno/FunctionalTests/pom.xml b/client/Java/Juno/FunctionalTests/pom.xml index 64fd11c1..15ec7336 100644 --- a/client/Java/Juno/FunctionalTests/pom.xml +++ b/client/Java/Juno/FunctionalTests/pom.xml @@ -76,7 +76,7 @@ limitations under the License. org.xerial.snappy snappy-java - 1.1.9.1 + 1.1.10.1 org.testng @@ -131,7 +131,7 @@ limitations under the License. io.netty netty-handler - 4.1.82.Final + 4.1.94.Final commons-lang diff --git a/client/Java/Juno/juno-client-impl/pom.xml b/client/Java/Juno/juno-client-impl/pom.xml index 6861c63b..d0a2c597 100644 --- a/client/Java/Juno/juno-client-impl/pom.xml +++ b/client/Java/Juno/juno-client-impl/pom.xml @@ -71,7 +71,7 @@ limitations under the License. io.netty netty-handler - 4.1.82.Final + 4.1.94.Final org.powermock @@ -124,7 +124,7 @@ limitations under the License. org.xerial.snappy snappy-java - 1.1.9.1 + 1.1.10.1 javax.inject diff --git a/client/Java/examples/client/junoReferenceApp/junoreferenceAppService/pom.xml b/client/Java/examples/client/junoReferenceApp/junoreferenceAppService/pom.xml index 37c2f1b0..780a3aa8 100644 --- a/client/Java/examples/client/junoReferenceApp/junoreferenceAppService/pom.xml +++ b/client/Java/examples/client/junoReferenceApp/junoreferenceAppService/pom.xml @@ -136,7 +136,7 @@ limitations under the License. org.springframework.boot spring-boot-autoconfigure - 2.6.7 + 2.6.15 org.springframework.boot diff --git a/client/Ruby/README.md b/client/Ruby/README.md new file mode 100644 index 00000000..272a4dca --- /dev/null +++ b/client/Ruby/README.md @@ -0,0 +1,38 @@ +# juno-ruby-client +Ruby client for JunoDB
+ +[Documentation](https://github.com/VaibhavA19/junodb/tree/dev/client/Ruby/docs)
+[SampleScript](https://github.com/VaibhavA19/junodb/blob/dev/client/Ruby/sample.rb)
+[ConfigFile](https://github.com/VaibhavA19/junodb/blob/dev/client/Ruby/juno.yml) + +### Work Directory: [juno] +# Gem Tasks +### Build gem +``` +cd juno +rake build +``` + +### Install gem +``` +cd juno +rake install +``` + +### Execute tests +``` +cd juno +rake spec +``` + +### Execute rubocop linitng +``` +cd juno +rake lint +``` + +### Update documentation +``` +cd juno +rake yard:document +``` diff --git a/client/Ruby/docs/Juno.html b/client/Ruby/docs/Juno.html new file mode 100644 index 00000000..76931cd3 --- /dev/null +++ b/client/Ruby/docs/Juno.html @@ -0,0 +1,301 @@ + + + + + + + Module: Juno + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Juno + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/constants.rb,
+ lib/juno/logger.rb,
lib/juno/version.rb,
lib/juno/Utils/utils.rb,
lib/juno/Config/config.rb,
lib/juno/server_status.rb,
lib/juno/IO/JunoMessage.rb,
lib/juno/Net/worker_pool.rb,
lib/juno/Net/io_processor.rb,
lib/juno/Net/ping_message.rb,
lib/juno/Config/properties.rb,
lib/juno/IO/ProtocolHeader.rb,
lib/juno/Net/request_queue.rb,
lib/juno/Client/cache_store.rb,
lib/juno/Client/sync_client.rb,
lib/juno/Net/base_processor.rb,
lib/juno/Net/client_handler.rb,
lib/juno/Utils/client_utils.rb,
lib/juno/Client/juno_request.rb,
lib/juno/Client/react_client.rb,
lib/juno/IO/OperationMessage.rb,
lib/juno/IO/PayloadComponent.rb,
lib/juno/Client/juno_response.rb,
lib/juno/Config/config_reader.rb,
lib/juno/IO/MetadataComponent.rb,
lib/juno/Client/operation_type.rb,
lib/juno/Client/record_context.rb,
lib/juno/Config/config_provider.rb,
lib/juno/Client/operation_status.rb,
lib/juno/Config/default_properties.rb,
lib/juno/IO/MetadataComponentTemplate.rb
+
+
+ +
+ +

Overview

+
+ +

Top module for juno client

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Client, ClientUtils, IO, Net + + + + Classes: Config, ConfigProvider, ConfigReader, DefaultProperties, Logger, Properties, ServerStatus, Utils + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
VERSION = + +
+
'0.1.0'
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .configureObject + + + + + +

+ + + + +
+
+
+
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+
+
# File 'lib/juno/Config/config.rb', line 105
+
+def self.configure
+  if @juno_config.nil?
+    config_reader = Juno::ConfigReader.new
+    yield config_reader
+    if !config_reader.file_path.nil?
+      @juno_config = Config.new(ConfigProvider.new(config_reader.file_path, config_reader.source_format, nil),
+                                log_file: config_reader.log_file, ssl_cert_file: config_reader.ssl_cert_file,
+                                ssl_key_file: config_reader.ssl_key_file)
+      @LOGGER = Juno::Logger.instance
+    elsif !config_reader.url.nil? # URL should URI Object
+      # @juno_config = Config.new(ConfigProvider.new(@juno_config.file_path, @juno_config.source_format, nil))
+    else
+      raise 'No file or url provided'
+    end
+  else
+    Juno::Logger.instance.warn('Juno client cannot be reconfigured')
+  end
+end
+
+
+ +
+

+ + .juno_configObject + + + + + +

+ + + + +
+
+
+
+124
+125
+126
+127
+128
+
+
# File 'lib/juno/Config/config.rb', line 124
+
+def self.juno_config
+  raise 'Please configure the properties using Juno.configure' if @juno_config.nil?
+
+  @juno_config
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client.html b/client/Ruby/docs/Juno/Client.html new file mode 100644 index 00000000..5f989283 --- /dev/null +++ b/client/Ruby/docs/Juno/Client.html @@ -0,0 +1,128 @@ + + + + + + + Module: Juno::Client + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Juno::Client + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/cache_store.rb,
+ lib/juno/Client/sync_client.rb,
lib/juno/Client/juno_request.rb,
lib/juno/Client/react_client.rb,
lib/juno/Client/juno_response.rb,
lib/juno/Client/operation_type.rb,
lib/juno/Client/record_context.rb,
lib/juno/Client/operation_status.rb
+
+
+ +
+ +

Overview

+
+ +

Module for code exposed to the developer

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: CacheStore, JunoRequest, JunoResponse, OperationStatus, OperationType, ReactClient, RecordContext, SyncClient + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/CacheStore.html b/client/Ruby/docs/Juno/Client/CacheStore.html new file mode 100644 index 00000000..c1e16bfb --- /dev/null +++ b/client/Ruby/docs/Juno/Client/CacheStore.html @@ -0,0 +1,557 @@ + + + + + + + Class: Juno::Client::CacheStore + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::CacheStore + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/cache_store.rb
+
+ +
+ +

Overview

+
+ +

Cache store for ruby on rails

+ + +
+
+
+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeCacheStore + + + + + +

+
+ +

Returns a new instance of CacheStore.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Client/cache_store.rb', line 9
+
+def initialize
+  @react_client = Juno::Client::ReactClient.new
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .supports_cache_versioning?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/juno/Client/cache_store.rb', line 27
+
+def self.supports_cache_versioning?
+  true
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #delete(key) ⇒ Object + + + + + +

+ + + + +
+
+
+
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/juno/Client/cache_store.rb', line 31
+
+def delete(key)
+  future_obj = @react_client.destroy(key).wait
+  return false if future_obj.nil? || future_obj.rejected?
+
+  future_obj.value.status[:code] == Juno::Client::OperationStatus::SUCCESS[:code]
+end
+
+
+ +
+

+ + #exist?(key) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+
+
# File 'lib/juno/Client/cache_store.rb', line 38
+
+def exist?(key)
+  !read(key).nil?
+end
+
+
+ +
+

+ + #read(key, options = {}) ⇒ Object + + + + + +

+ + + + +
+
+
+
+22
+23
+24
+25
+
+
# File 'lib/juno/Client/cache_store.rb', line 22
+
+def read(key, options = {})
+  future_obj = @react_client.get(key).wait
+  read_response(future_obj, options[:version])
+end
+
+
+ +
+

+ + #write(key, value, _options = {}) ⇒ Object + + + + + +

+ + + + +
+
+
+
+13
+14
+15
+16
+17
+18
+19
+20
+
+
# File 'lib/juno/Client/cache_store.rb', line 13
+
+def write(key, value, _options = {})
+  future_obj = @react_client.set(key, value).wait
+  return false if future_obj.nil?
+
+  raise future_obj.reason if future_obj.rejected?
+
+  future_obj.value.status[:txnOk]
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/JunoRequest.html b/client/Ruby/docs/Juno/Client/JunoRequest.html new file mode 100644 index 00000000..7358430f --- /dev/null +++ b/client/Ruby/docs/Juno/Client/JunoRequest.html @@ -0,0 +1,905 @@ + + + + + + + Class: Juno::Client::JunoRequest + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::JunoRequest + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/juno_request.rb
+
+ +
+ +

Overview

+
+ +

Request Object created from application request

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Type + + +

+ + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #creation_time ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute creation_time.

    +
    + +
  • + + +
  • + + + #key ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute key.

    +
    + +
  • + + +
  • + + + #time_to_live_s ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute time_to_live_s.

    +
    + +
  • + + +
  • + + + #type ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute type.

    +
    + +
  • + + +
  • + + + #value ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute value.

    +
    + +
  • + + +
  • + + + #version ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute version.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(key:, version:, type:, value: nil, time_to_live_s: nil, creation_time: nil) ⇒ JunoRequest + + + + + +

+
+ +

Constructor for JunoRequest

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + version + + + (Integer) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + version + + + (Juno::JunoRequest::Type) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + type + + + (String) + + + + — +
    +

    value for the document (optional, default: 1 byte string: 0.chr)

    +
    + +
  • + +
  • + + type + + + (Integer) + + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
  • + + type + + + (Integer) + + + + — +
    +

    Time to live for the document (optional, default: initialized to Time.now in JunoMessage)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+
+
# File 'lib/juno/Client/juno_request.rb', line 25
+
+def initialize(key:, version:, type:, value: nil, time_to_live_s: nil, creation_time: nil)
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @key = key
+  @version = version.to_i
+  @type = type
+  @value = value.to_s.empty? ? 0.chr : value.to_s
+  @time_to_live_s = time_to_live_s.to_i
+  @creation_time = creation_time
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #creation_timeObject + + + + + +

+
+ +

Returns the value of attribute creation_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def creation_time
+  @creation_time
+end
+
+
+ + + +
+

+ + #keyObject + + + + + +

+
+ +

Returns the value of attribute key.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def key
+  @key
+end
+
+
+ + + +
+

+ + #time_to_live_sObject + + + + + +

+
+ +

Returns the value of attribute time_to_live_s.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def time_to_live_s
+  @time_to_live_s
+end
+
+
+ + + +
+

+ + #typeObject + + + + + +

+
+ +

Returns the value of attribute type.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def type
+  @type
+end
+
+
+ + + +
+

+ + #valueObject + + + + + +

+
+ +

Returns the value of attribute value.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def value
+  @value
+end
+
+
+ + + +
+

+ + #versionObject + + + + + +

+
+ +

Returns the value of attribute version.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/juno/Client/juno_request.rb', line 16
+
+def version
+  @version
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #==(other) ⇒ Object + + + + + +

+ + + + +
+
+
+
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/juno/Client/juno_request.rb', line 36
+
+def ==(other)
+  return false unless other.is_a?(JunoRequest)
+
+  other.key == @key &&
+    other.version == @version &&
+    other.type == @type &&
+    other.value == @value &&
+    other.time_to_live_s == @time_to_live_s &&
+    other.creation_time == @creation_time
+end
+
+
+ +
+

+ + #to_sObject + + + + + +

+
+ +

Function to serialize JunoRequest

+ + +
+
+
+ + +
+ + + + +
+
+
+
+48
+49
+50
+
+
# File 'lib/juno/Client/juno_request.rb', line 48
+
+def to_s
+  "JunoRequest key:#{@key} version:#{@version} type:#{@type}, value: #{@value}, time_to_live: #{@time_to_live}, creation_time: #{@creation_time}"
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/JunoRequest/Type.html b/client/Ruby/docs/Juno/Client/JunoRequest/Type.html new file mode 100644 index 00000000..619822d7 --- /dev/null +++ b/client/Ruby/docs/Juno/Client/JunoRequest/Type.html @@ -0,0 +1,157 @@ + + + + + + + Class: Juno::Client::JunoRequest::Type + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::JunoRequest::Type + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/juno_request.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
CREATE = + +
+
1
+ +
GET = + +
+
2
+ +
UPDATE = + +
+
3
+ +
SET = + +
+
4
+ +
DESTROY = + +
+
5
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/JunoResponse.html b/client/Ruby/docs/Juno/Client/JunoResponse.html new file mode 100644 index 00000000..3aab10d2 --- /dev/null +++ b/client/Ruby/docs/Juno/Client/JunoResponse.html @@ -0,0 +1,616 @@ + + + + + + + Class: Juno::Client::JunoResponse + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::JunoResponse + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/juno_response.rb
+
+ +
+ +

Overview

+
+ +

Response sent to the application

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #key ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute key.

    +
    + +
  • + + +
  • + + + #record_context ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute record_context.

    +
    + +
  • + + +
  • + + + #status ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute status.

    +
    + +
  • + + +
  • + + + #value ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute value.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(key:, value:, version:, time_to_live_s:, creation_time:, operation_status:) ⇒ JunoResponse + + + + + +

+
+ +

Returns a new instance of JunoResponse.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + status + + + (Juno::Client::OperationStatus) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + version + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + creation_time + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + time_to_live_s + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+
+
# File 'lib/juno/Client/juno_response.rb', line 15
+
+def initialize(key:, value:, version:, time_to_live_s:, creation_time:, operation_status:)
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @key = key
+  @status = operation_status
+  @value = value
+  @record_context = Juno::Client::RecordContext.new(key: key, version: version, creation_time: creation_time,
+                                                    time_to_live_s: time_to_live_s)
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #keyObject + + + + + +

+
+ +

Returns the value of attribute key.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Client/juno_response.rb', line 7
+
+def key
+  @key
+end
+
+
+ + + +
+

+ + #record_contextObject + + + + + +

+
+ +

Returns the value of attribute record_context.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Client/juno_response.rb', line 7
+
+def record_context
+  @record_context
+end
+
+
+ + + +
+

+ + #statusObject + + + + + +

+
+ +

Returns the value of attribute status.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Client/juno_response.rb', line 7
+
+def status
+  @status
+end
+
+
+ + + +
+

+ + #valueObject + + + + + +

+
+ +

Returns the value of attribute value.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Client/juno_response.rb', line 7
+
+def value
+  @value
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/OperationStatus.html b/client/Ruby/docs/Juno/Client/OperationStatus.html new file mode 100644 index 00000000..37fb85f3 --- /dev/null +++ b/client/Ruby/docs/Juno/Client/OperationStatus.html @@ -0,0 +1,344 @@ + + + + + + + Class: Juno::Client::OperationStatus + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::OperationStatus + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/operation_status.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
SUCCESS = + +
+
{ code: 0, error_msg: 'No error', txnOk: true }.freeze
+ +
NO_KEY = + +
+
{ code: 1, error_msg: 'Key not found', txnOk: true }.freeze
+ +
BAD_PARAM = + +
+
{ code: 2, error_msg: 'Bad parameter', txnOk: false }.freeze
+ +
UNIQUE_KEY_VIOLATION = + +
+
{ code: 3, error_msg: 'Duplicate key', txnOk: true }.freeze
+ +
RECORD_LOCKED = + +
+
{ code: 4, error_msg: 'Record Locked', txnOk: true }.freeze
+ +
ILLEGAL_ARGUMENT = + +
+
{ code: 5, error_msg: 'Illegal argument', txnOk: false }.freeze
+ +
CONDITION_VIOLATION = + +
+
{ code: 6, error_msg: 'Condition in the request violated', txnOk: true }.freeze
+ +
INTERNAL_ERROR = + +
+
{ code: 7, error_msg: 'Internal error', txnOk: false }.freeze
+ +
QUEUE_FULL = + +
+
{ code: 8, error_msg: 'Outbound client queue full', txnOk: false }.freeze
+ +
NO_STORAGE = + +
+
{ code: 9, error_msg: 'No storage server running', txnOk: false }.freeze
+ +
TTL_EXTEND_FAILURE = + +
+
{ code: 10, error_msg: 'Failure to extend TTL on get', txnOk: true }.freeze
+ +
RESPONSE_TIMEOUT = + +
+
{ code: 11, error_msg: 'Response Timed out', txnOk: false }.freeze
+ +
CONNECTION_ERROR = + +
+
{ code: 12, error_msg: 'Connection Error', txnOk: false }.freeze
+ +
UNKNOWN_ERROR = + +
+
{ code: 13, error_msg: 'Unknown Error', txnOk: false }.freeze
+ +
@@status_code_map = + +
+
nil
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .get(status_code) ⇒ Object + + + + + +

+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+
+
# File 'lib/juno/Client/operation_status.rb', line 33
+
+def self.get(status_code)
+  initialize_map if @@status_code_map.nil?
+  return @@status_code_map[status_code] if @@status_code_map.key?(status_code)
+
+  INTERNAL_ERROR
+end
+
+
+ +
+

+ + .initialize_mapObject + + + + + +

+ + + + +
+
+
+
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/juno/Client/operation_status.rb', line 24
+
+def self.initialize_map
+  @@status_code_map = {}
+
+  constants.each do |const|
+    const_obj = const_get(const)
+    @@status_code_map[const_obj[:code]] = const_obj
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/OperationType.html b/client/Ruby/docs/Juno/Client/OperationType.html new file mode 100644 index 00000000..a207babb --- /dev/null +++ b/client/Ruby/docs/Juno/Client/OperationType.html @@ -0,0 +1,199 @@ + + + + + + + Class: Juno::Client::OperationType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::OperationType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/operation_type.rb
+
+ +
+ +

Overview

+
+ +

Constant for JunoRequest operation type

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
Nop = + +
+
{
+  code: 0,
+  str: 'NOP'
+}.freeze
+ +
Create = + +
+
{
+  code: 1,
+  str: 'CREATE'
+}.freeze
+ +
Get = + +
+
{
+  code: 2,
+  str: 'GET'
+}.freeze
+ +
Update = + +
+
{
+  code: 3,
+  str: 'UPDATE'
+}.freeze
+ +
Set = + +
+
{
+  code: 4,
+  str: 'SET'
+}.freeze
+ +
CompareAndSet = + +
+
{
+  code: 5,
+  str: 'COMPAREANDSET'
+}.freeze
+ +
Destroy = + +
+
{
+  code: 6,
+  str: 'DESTROY'
+}.freeze
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/ReactClient.html b/client/Ruby/docs/Juno/Client/ReactClient.html new file mode 100644 index 00000000..45993963 --- /dev/null +++ b/client/Ruby/docs/Juno/Client/ReactClient.html @@ -0,0 +1,1347 @@ + + + + + + + Class: Juno::Client::ReactClient + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::ReactClient + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/react_client.rb
+
+ +
+ +

Overview

+
+ +

Async Client for Juno

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
MAX_OPERATION_RETRY = +
+
+ +

Constants for operation retry

+ + +
+
+
+ + +
+
+
1
+ +
MAX_RETRY_INTERVAL = +
+
+ +

msec

+ + +
+
+
+ + +
+
+
15
+ +
MIN_RETRY_INTERVAL = +
+
+ +

msec

+ + +
+
+
+ + +
+
+
10
+ +
@@OPAQUE_GENERATOR = +
+
+ +

@ Global Opaque generator. Uses ConcurrentFixnum for thread safety

+ + +
+
+
+ + +
+
+
Concurrent::AtomicFixnum.new(-1)
+ +
@@fail_count = +
+
+ +

@ Variable to count failed requests

+ + +
+
+
+ + +
+
+
Concurrent::AtomicFixnum.new(0)
+ +
@@received = +
+
+ +

@ Variable to count responses received

+ + +
+
+
+ + +
+
+
Concurrent::AtomicFixnum.new(0)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeReactClient + + + + + +

+
+ +

Returns a new instance of ReactClient.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+
+
# File 'lib/juno/Client/react_client.rb', line 33
+
+def initialize
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @request_queue = Juno::Net::RequestQueue.instance
+  @executor = Concurrent::ThreadPoolExecutor.new(min_threads: 4, max_threads: 16, max_queue: 10_000)
+  @count = 0
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .failed_countObject + + + + + +

+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/juno/Client/react_client.rb', line 25
+
+def self.failed_count
+  @@fail_count.value
+end
+
+
+ +
+

+ + .op_countObject + + + + + +

+ + + + +
+
+
+
+21
+22
+23
+
+
# File 'lib/juno/Client/react_client.rb', line 21
+
+def self.op_count
+  @@OPAQUE_GENERATOR.value
+end
+
+
+ +
+

+ + .recvObject + + + + + +

+ + + + +
+
+
+
+29
+30
+31
+
+
# File 'lib/juno/Client/react_client.rb', line 29
+
+def self.recv
+  @@received.value
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(record_context, value, ttl) ⇒ Object + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+
+
# File 'lib/juno/Client/react_client.rb', line 86
+
+def compare_and_set(record_context, value, ttl)
+  unless record_context.is_a?(Juno::Client::RecordContext)
+    raise ArgumentError, 'recird context should be of type Juno::Client::RecordContext'
+  end
+  raise ArgumentError, 'Version cannot be less than 1' if record_context.version.to_i < 1
+
+  juno_request = Juno::Client::JunoRequest.new(key: record_context.key.to_s,
+                                               value: value,
+                                               version: record_context.version.to_i,
+                                               type: Juno::Client::JunoRequest::Type::UPDATE,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+

+ + #create(key, value, ttl: nil) ⇒ Boolean + + + + + +

+
+ +

Function to create new key value pair

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +
    +

    True if operation submited successfully, else false

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+
+
# File 'lib/juno/Client/react_client.rb', line 56
+
+def create(key, value, ttl: nil)
+  juno_request = Juno::Client::JunoRequest.new(key: key,
+                                               value: value,
+                                               version: 0,
+                                               type: Juno::Client::JunoRequest::Type::CREATE,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+

+ + #destroy(key, ttl: nil) ⇒ Object + + + + Also known as: + delete + + + + +

+ + + + +
+
+
+
+131
+132
+133
+134
+135
+136
+137
+138
+139
+
+
# File 'lib/juno/Client/react_client.rb', line 131
+
+def destroy(key, ttl: nil)
+  juno_request = Juno::Client::JunoRequest.new(key: key,
+                                               value: '',
+                                               version: 0,
+                                               type: Juno::Client::JunoRequest::Type::DESTROY,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+

+ + #exist?(key) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+144
+
+
# File 'lib/juno/Client/react_client.rb', line 144
+
+def exist?(key); end
+
+
+ +
+

+ + #get(key, ttl: nil) ⇒ Juno::Client::JunoResponse + + + + Also known as: + read + + + + +

+
+ +

Function to get existing key value pair

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+ + +

See Also:

+ + +
+ + + + +
+
+
+
+108
+109
+110
+111
+112
+113
+114
+115
+116
+
+
# File 'lib/juno/Client/react_client.rb', line 108
+
+def get(key, ttl: nil)
+  juno_request = Juno::Client::JunoRequest.new(key: key,
+                                               value: '',
+                                               version: 0,
+                                               type: Juno::Client::JunoRequest::Type::GET,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+

+ + #set(key, value, ttl: nil) ⇒ Boolean + + + + Also known as: + write + + + + +

+
+ +

Function to set value for given key

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +
    +

    True if operation submited successfully, else false

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+73
+74
+75
+76
+77
+78
+79
+80
+81
+
+
# File 'lib/juno/Client/react_client.rb', line 73
+
+def set(key, value, ttl: nil)
+  juno_request = Juno::Client::JunoRequest.new(key: key,
+                                               value: value,
+                                               version: 0,
+                                               type: Juno::Client::JunoRequest::Type::SET,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+

+ + #stopObject + + + + + +

+ + + + +
+
+
+
+41
+42
+43
+44
+45
+46
+47
+
+
# File 'lib/juno/Client/react_client.rb', line 41
+
+def stop
+  @LOGGER.info(@PROG_NAME) { 'stop initiated by client' }
+  @request_queue.stop
+  @executor.shutdown
+  @executor.wait_for_termination
+  @executor.kill
+end
+
+
+ +
+

+ + #update(key, value, ttl: nil) ⇒ Object + + + + + +

+ + + + +
+
+
+
+121
+122
+123
+124
+125
+126
+127
+128
+129
+
+
# File 'lib/juno/Client/react_client.rb', line 121
+
+def update(key, value, ttl: nil)
+  juno_request = Juno::Client::JunoRequest.new(key: key,
+                                               value: value,
+                                               version: 0,
+                                               type: Juno::Client::JunoRequest::Type::UPDATE,
+                                               time_to_live_s: ttl,
+                                               creation_time: Time.now.to_i)
+  process_single(juno_request)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/RecordContext.html b/client/Ruby/docs/Juno/Client/RecordContext.html new file mode 100644 index 00000000..db0d8e5b --- /dev/null +++ b/client/Ruby/docs/Juno/Client/RecordContext.html @@ -0,0 +1,579 @@ + + + + + + + Class: Juno::Client::RecordContext + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::RecordContext + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/record_context.rb
+
+ +
+ + + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #creation_time ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute creation_time.

    +
    + +
  • + + +
  • + + + #key ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute key.

    +
    + +
  • + + +
  • + + + #time_to_live_s ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute time_to_live_s.

    +
    + +
  • + + +
  • + + + #version ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute version.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(key:, version:, creation_time:, time_to_live_s:) ⇒ RecordContext + + + + + +

+
+ +

Returns a new instance of RecordContext.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + version + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + creation_time + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + time_to_live_s + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+18
+19
+
+
# File 'lib/juno/Client/record_context.rb', line 12
+
+def initialize(key:, version:, creation_time:, time_to_live_s:)
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @key = key
+  @version = version
+  @creation_time = creation_time
+  @time_to_live_s = time_to_live_s
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #creation_timeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute creation_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/Client/record_context.rb', line 6
+
+def creation_time
+  @creation_time
+end
+
+
+ + + +
+

+ + #keyObject (readonly) + + + + + +

+
+ +

Returns the value of attribute key.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/Client/record_context.rb', line 6
+
+def key
+  @key
+end
+
+
+ + + +
+

+ + #time_to_live_sObject (readonly) + + + + + +

+
+ +

Returns the value of attribute time_to_live_s.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/Client/record_context.rb', line 6
+
+def time_to_live_s
+  @time_to_live_s
+end
+
+
+ + + +
+

+ + #versionObject (readonly) + + + + + +

+
+ +

Returns the value of attribute version.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/Client/record_context.rb', line 6
+
+def version
+  @version
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Client/SyncClient.html b/client/Ruby/docs/Juno/Client/SyncClient.html new file mode 100644 index 00000000..1e2e052f --- /dev/null +++ b/client/Ruby/docs/Juno/Client/SyncClient.html @@ -0,0 +1,844 @@ + + + + + + + Class: Juno::Client::SyncClient + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Client::SyncClient + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Client/sync_client.rb
+
+ +
+ +

Overview

+
+ +

Async Client for Juno

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeSyncClient + + + + + +

+
+ +

Returns a new instance of SyncClient.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Client/sync_client.rb', line 9
+
+def initialize
+  @react_client = Juno::Client::ReactClient.new
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #compare_and_set(record_context, value, ttl: nil) ⇒ Object + + + + + +

+ + + + +
+
+
+
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+
+
# File 'lib/juno/Client/sync_client.rb', line 64
+
+def compare_and_set(record_context, value, ttl: nil)
+  juno_resp = nil
+  begin
+    juno_resp = @react_client.compare_and_set(record_context, value, ttl)
+  rescue ArgumentError => e
+    raise e.message
+  end
+
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+

+ + #create(key, value, ttl: nil) ⇒ Juno::Client::JunoResponse + + + + + +

+
+ +

Function to create new key value pair

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/juno/Client/sync_client.rb', line 18
+
+def create(key, value, ttl: nil)
+  juno_resp = @react_client.create(key, value, ttl: ttl).wait
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+

+ + #destroy(key, ttl: nil) ⇒ Object + + + + + +

+ + + + +
+
+
+
+79
+80
+81
+82
+83
+84
+85
+86
+
+
# File 'lib/juno/Client/sync_client.rb', line 79
+
+def destroy(key, ttl: nil)
+  juno_resp = @react_client.destroy(key.to_s, ttl: ttl).wait
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+

+ + #get(key, ttl: nil) ⇒ Juno::Client::JunoResponse + + + + + +

+
+ +

Function to get existing key value pair

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+46
+47
+48
+49
+50
+51
+52
+53
+
+
# File 'lib/juno/Client/sync_client.rb', line 46
+
+def get(key, ttl: nil)
+  juno_resp = @react_client.get(key.to_s, ttl: ttl).wait
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+

+ + #set(key, value, ttl: nil) ⇒ Juno::Client::JunoResponse + + + + + +

+
+ +

Function to set value for given key

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    key for the document (required)

    +
    + +
  • + +
  • + + value + + + (String) + + + + — +
    +

    value for the document (required)

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: nil) + + + — +
    +

    Time to live for the document (optional, default: read from config file)

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+32
+33
+34
+35
+36
+37
+38
+39
+
+
# File 'lib/juno/Client/sync_client.rb', line 32
+
+def set(key, value, ttl: nil)
+  juno_resp = @react_client.set(key.to_s, value.to_s, ttl: ttl).wait
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+

+ + #update(key, value, ttl: nil) ⇒ Object + + + + + +

+ + + + +
+
+
+
+55
+56
+57
+58
+59
+60
+61
+62
+
+
# File 'lib/juno/Client/sync_client.rb', line 55
+
+def update(key, value, ttl: nil)
+  juno_resp = @react_client.update(key.to_s, value.to_s, ttl: ttl).wait
+  return nil if juno_resp.nil?
+
+  raise juno_resp.reason if juno_resp.rejected?
+
+  juno_resp.value # JunoResponse
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/ClientUtils.html b/client/Ruby/docs/Juno/ClientUtils.html new file mode 100644 index 00000000..da69bfb2 --- /dev/null +++ b/client/Ruby/docs/Juno/ClientUtils.html @@ -0,0 +1,676 @@ + + + + + + + Module: Juno::ClientUtils + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Juno::ClientUtils + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Utils/client_utils.rb
+
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .compressed_value(value) ⇒ Object + + + + + +

+ + + + +
+
+
+
+42
+43
+44
+45
+46
+47
+48
+
+
# File 'lib/juno/Utils/client_utils.rb', line 42
+
+def self.compressed_value(value)
+  compressed_value = Snappy.deflate(value)
+  compression_achieved = 100 - (compressed_value.length * 100) / value.length
+  [compressed_value, compression_achieved]
+rescue Exception
+  [value, false]
+end
+
+
+ +
+

+ + .create_operation_message(juno_message, opaque) ⇒ Object + + + + + +

+ + + + +
+
+
+
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+
+
# File 'lib/juno/Utils/client_utils.rb', line 5
+
+def self.create_operation_message(juno_message, opaque)
+  protocol_header = Juno::IO::ProtocolHeader.new
+  protocol_header.version = juno_message.version
+  protocol_header.opcode = juno_message.operation_type
+  protocol_header.opaque = opaque
+
+   = Juno::IO::MetadataComponent.new
+  if juno_message.time_to_live_s.to_i.positive?
+    .set_time_to_live(juno_message.time_to_live_s.to_i)
+  end
+  .set_version(juno_message.version)
+
+  if [Juno::IO::JunoMessage::OperationType::CREATE,
+      Juno::IO::JunoMessage::OperationType::SET].include?(juno_message.operation_type)
+    .set_creation_time(Time.now.to_i)
+  end
+
+  .set_expiration_time((Time.now + juno_message.time_to_live_s).to_i) # what ?
+  .set_request_uuid(juno_message.request_uuid)
+  .set_source_info(app_name: juno_message.app_name, ip: juno_message.ip, port: juno_message.port)
+  .set_originator_request_id # what
+
+  payload_component = Juno::IO::PayloadComponent.new
+  payload_component.namespace = juno_message.namespace
+  payload_component.payload_key = juno_message.key
+  payload_component.set_value(juno_message.value, juno_message.compression_type)
+
+  operation_message = Juno::IO::OperationMessage.new
+  operation_message.protocol_header = protocol_header
+  operation_message. = 
+  operation_message.payload_component = payload_component
+
+  juno_message.message_size = operation_message.size
+
+  operation_message
+end
+
+
+ +
+

+ + .decode_operation_message(operation_message) ⇒ Object + + + + + +

+ + + + +
+
+
+
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+
+
# File 'lib/juno/Utils/client_utils.rb', line 111
+
+def self.decode_operation_message(operation_message)
+  return nil unless operation_message.is_a?(Juno::IO::OperationMessage)
+
+  juno_message = Juno::IO::JunoMessage.new
+  opcode = operation_message.protocol_header.opcode.to_i
+  juno_message.operation_type = Juno::IO::JunoMessage::OperationType.get(opcode)
+
+  server_status = operation_message.protocol_header.status.to_i
+  juno_message.server_status = Juno::ServerStatus.get(server_status)
+
+  juno_message.message_size = operation_message.protocol_header.message_size.to_i
+
+  unless operation_message..nil?
+     = operation_message.
+    juno_message.time_to_live_s = .time_to_live.to_i
+    juno_message.ip = .ip
+    juno_message.port = .port
+    juno_message.version = .version.to_i
+    juno_message.creation_time = .creation_time.to_i
+    juno_message.expiration_time = .expiration_time.to_i
+    juno_message.request_uuid = .request_uuid
+    juno_message.app_name = .app_name
+    juno_message.last_modification = .last_modification.to_i
+    juno_message.originator_request_id = .originator_request_id.to_s
+    juno_message.correlation_id = .correlation_id
+    juno_message.request_handling_time = .request_handling_time.to_i
+    # juno_message.request_start_time = metadata_component.
+    # expiry
+  end
+
+  unless operation_message.payload_component.nil?
+    juno_message.namespace = operation_message.payload_component.namespace.to_s
+    juno_message.key = operation_message.payload_component.payload_key.to_s
+    juno_message.is_compressed = operation_message.payload_component.compressed?
+    juno_message.compression_type = operation_message.payload_component.compression_type.to_i
+    juno_message.value = if operation_message.payload_component.payload_length.to_i.zero?
+                           juno_message.compression_achieved = 0
+                           nil
+                         elsif juno_message.is_compressed
+                           compressed_value = operation_message.payload_component.value.to_s
+                           decompressed_value = decompress_value(compressed_value)
+                           juno_message.compression_achieved = 100 - (compressed_value.length / decompressed_value.length.to_f) * 100.0
+                           decompressed_value
+                         else
+                           juno_message.compression_achieved = 0
+                           operation_message.payload_component.value.to_s
+                         end
+  end
+
+  juno_message
+end
+
+
+ +
+

+ + .decompress_value(value) ⇒ Object + + + + + +

+ + + + +
+
+
+
+50
+51
+52
+53
+54
+55
+
+
# File 'lib/juno/Utils/client_utils.rb', line 50
+
+def self.decompress_value(value)
+  Snappy.inflate(value)
+rescue Exception
+  # Log failure
+  value
+end
+
+
+ +
+

+ + .validate!(juno_request) ⇒ Object + + + + + +

+
+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+
+
# File 'lib/juno/Utils/client_utils.rb', line 57
+
+def self.validate!(juno_request)
+  return false unless juno_request.is_a?(Juno::Client::JunoRequest)
+
+  raise ArgumentError, 'Juno request key cannot be empty' if juno_request.key.to_s.nil?
+
+  juno_request.time_to_live_s = Juno.juno_config.default_lifetime unless juno_request.time_to_live_s.to_i.positive?
+
+  if juno_request.time_to_live_s > Juno.juno_config.max_lifetime || juno_request.time_to_live_s.negative?
+    raise ArgumentError,
+          "Record time_to_live_s (#{juno_request.time_to_live_s}s) cannot be greater than  #{Juno.juno_config.max_lifetime}s or negative ."
+  end
+
+  if juno_request.key.to_s.size > Juno.juno_config.max_key_size
+    raise ArgumentError,
+          "Key size cannot be greater than #{Juno.juno_config.max_key_size}"
+  end
+
+  if juno_request.key.to_s.size > Juno.juno_config.max_key_size
+    raise ArgumentError,
+          "Key size cannot be greater than #{Juno.juno_config.max_key_size}"
+  end
+
+  juno_message = Juno::IO::JunoMessage.new
+  juno_message.key = juno_request.key
+  juno_message.version = juno_request.version
+  juno_message.operation_type = juno_request.type
+  juno_message.time_to_live_s = juno_request.time_to_live_s
+  juno_message.creation_time = juno_request.creation_time
+  juno_message.namespace = Juno.juno_config.record_namespace
+  juno_message.app_name = Juno.juno_config.app_name
+  juno_message.request_uuid = UUIDTools::UUID.random_create.to_s
+  juno_message.ip = IPAddr.new(Juno::Utils.local_ips[0])
+  juno_message.port = 0
+
+  unless [Juno::Client::JunoRequest::Type::GET,
+          Juno::Client::JunoRequest::Type::DESTROY].include?(juno_request.type)
+    payload_value = juno_request.value
+    is_compressed = false
+    compression_achieved = 0
+    if Juno.juno_config.use_payload_compression && value.length > 1024
+      payload_value, compression_achieved = compressed_value(value)
+      is_compressed = true if compression_achieved.positive?
+    end
+    juno_message.is_compressed = is_compressed
+    juno_message.value = payload_value
+    juno_message.compression_achieved = compression_achieved
+    juno_message.compression_type = is_compressed ? Juno::IO::CompressionType::Snappy : Juno::IO::CompressionType::None
+  end
+
+  juno_message
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Config.html b/client/Ruby/docs/Juno/Config.html new file mode 100644 index 00000000..45920a60 --- /dev/null +++ b/client/Ruby/docs/Juno/Config.html @@ -0,0 +1,2381 @@ + + + + + + + Class: Juno::Config + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Config + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/config.rb
+
+ +
+ +

Overview

+
+ +

Juno.configure do |config|

+ +
config.record_namespace = "kk"
+config.host = '10.138.38.83'
+config.port = 5080
+config.app_name = "TestApp"
+config.file_path = ""
+config.url = ""
+
+ +

end

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: Source + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
REQUIRED_PROPERTIES = + +
+
%i[host port app_name record_namespace log_file].freeze
+ +
+ + + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #app_name ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute app_name.

    +
    + +
  • + + +
  • + + + #bypass_ltm ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute bypass_ltm.

    +
    + +
  • + + +
  • + + + #config_prefix ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute config_prefix.

    +
    + +
  • + + +
  • + + + #connection_lifetime ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute connection_lifetime.

    +
    + +
  • + + +
  • + + + #connection_pool_size ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute connection_pool_size.

    +
    + +
  • + + +
  • + + + #connection_timeout ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute connection_timeout.

    +
    + +
  • + + +
  • + + + #default_lifetime ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute default_lifetime.

    +
    + +
  • + + +
  • + + + #host ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute host.

    +
    + +
  • + + +
  • + + + #log_file ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute log_file.

    +
    + +
  • + + +
  • + + + #max_connection_lifetime ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_connection_lifetime.

    +
    + +
  • + + +
  • + + + #max_connection_pool_size ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_connection_pool_size.

    +
    + +
  • + + +
  • + + + #max_connection_timeout ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_connection_timeout.

    +
    + +
  • + + +
  • + + + #max_key_size ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_key_size.

    +
    + +
  • + + +
  • + + + #max_lifetime ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_lifetime.

    +
    + +
  • + + +
  • + + + #max_namespace_length ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_namespace_length.

    +
    + +
  • + + +
  • + + + #max_response_timeout ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_response_timeout.

    +
    + +
  • + + +
  • + + + #max_value_size ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute max_value_size.

    +
    + +
  • + + +
  • + + + #operation_retry ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute operation_retry.

    +
    + +
  • + + +
  • + + + #port ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute port.

    +
    + +
  • + + +
  • + + + #reconnect_on_fail ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute reconnect_on_fail.

    +
    + +
  • + + +
  • + + + #record_namespace ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute record_namespace.

    +
    + +
  • + + +
  • + + + #response_timeout ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute response_timeout.

    +
    + +
  • + + +
  • + + + #ssl_cert_file ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute ssl_cert_file.

    +
    + +
  • + + +
  • + + + #ssl_key_file ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute ssl_key_file.

    +
    + +
  • + + +
  • + + + #use_payload_compression ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute use_payload_compression.

    +
    + +
  • + + +
  • + + + #use_ssl ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute use_ssl.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(config_provider, log_file:, ssl_cert_file: nil, ssl_key_file: nil) ⇒ Config + + + + + +

+
+ +

Returns a new instance of Config.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
+
# File 'lib/juno/Config/config.rb', line 22
+
+def initialize(config_provider, log_file:, ssl_cert_file: nil, ssl_key_file: nil)
+  @PROG_NAME = self.class.name
+  @log_file = log_file
+  @ssl_cert_file = ssl_cert_file
+  @ssl_key_file = ssl_key_file
+  @config = config_provider
+  read_all
+  validate!
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #app_nameObject (readonly) + + + + + +

+
+ +

Returns the value of attribute app_name.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def app_name
+  @app_name
+end
+
+
+ + + +
+

+ + #bypass_ltmObject (readonly) + + + + + +

+
+ +

Returns the value of attribute bypass_ltm.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def bypass_ltm
+  @bypass_ltm
+end
+
+
+ + + +
+

+ + #config_prefixObject (readonly) + + + + + +

+
+ +

Returns the value of attribute config_prefix.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def config_prefix
+  @config_prefix
+end
+
+
+ + + +
+

+ + #connection_lifetimeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute connection_lifetime.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def connection_lifetime
+  @connection_lifetime
+end
+
+
+ + + +
+

+ + #connection_pool_sizeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute connection_pool_size.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def connection_pool_size
+  @connection_pool_size
+end
+
+
+ + + +
+

+ + #connection_timeoutObject (readonly) + + + + + +

+
+ +

Returns the value of attribute connection_timeout.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def connection_timeout
+  @connection_timeout
+end
+
+
+ + + +
+

+ + #default_lifetimeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute default_lifetime.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def default_lifetime
+  @default_lifetime
+end
+
+
+ + + +
+

+ + #hostObject (readonly) + + + + + +

+
+ +

Returns the value of attribute host.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def host
+  @host
+end
+
+
+ + + +
+

+ + #log_fileObject (readonly) + + + + + +

+
+ +

Returns the value of attribute log_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def log_file
+  @log_file
+end
+
+
+ + + +
+

+ + #max_connection_lifetimeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_connection_lifetime.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_connection_lifetime
+  @max_connection_lifetime
+end
+
+
+ + + +
+

+ + #max_connection_pool_sizeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_connection_pool_size.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_connection_pool_size
+  @max_connection_pool_size
+end
+
+
+ + + +
+

+ + #max_connection_timeoutObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_connection_timeout.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_connection_timeout
+  @max_connection_timeout
+end
+
+
+ + + +
+

+ + #max_key_sizeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_key_size.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_key_size
+  @max_key_size
+end
+
+
+ + + +
+

+ + #max_lifetimeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_lifetime.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_lifetime
+  @max_lifetime
+end
+
+
+ + + +
+

+ + #max_namespace_lengthObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_namespace_length.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_namespace_length
+  @max_namespace_length
+end
+
+
+ + + +
+

+ + #max_response_timeoutObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_response_timeout.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_response_timeout
+  @max_response_timeout
+end
+
+
+ + + +
+

+ + #max_value_sizeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute max_value_size.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def max_value_size
+  @max_value_size
+end
+
+
+ + + +
+

+ + #operation_retryObject (readonly) + + + + + +

+
+ +

Returns the value of attribute operation_retry.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def operation_retry
+  @operation_retry
+end
+
+
+ + + +
+

+ + #portObject (readonly) + + + + + +

+
+ +

Returns the value of attribute port.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def port
+  @port
+end
+
+
+ + + +
+

+ + #reconnect_on_failObject (readonly) + + + + + +

+
+ +

Returns the value of attribute reconnect_on_fail.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def reconnect_on_fail
+  @reconnect_on_fail
+end
+
+
+ + + +
+

+ + #record_namespaceObject (readonly) + + + + + +

+
+ +

Returns the value of attribute record_namespace.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def record_namespace
+  @record_namespace
+end
+
+
+ + + +
+

+ + #response_timeoutObject (readonly) + + + + + +

+
+ +

Returns the value of attribute response_timeout.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def response_timeout
+  @response_timeout
+end
+
+
+ + + +
+

+ + #ssl_cert_fileObject (readonly) + + + + + +

+
+ +

Returns the value of attribute ssl_cert_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def ssl_cert_file
+  @ssl_cert_file
+end
+
+
+ + + +
+

+ + #ssl_key_fileObject (readonly) + + + + + +

+
+ +

Returns the value of attribute ssl_key_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def ssl_key_file
+  @ssl_key_file
+end
+
+
+ + + +
+

+ + #use_payload_compressionObject (readonly) + + + + + +

+
+ +

Returns the value of attribute use_payload_compression.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def use_payload_compression
+  @use_payload_compression
+end
+
+
+ + + +
+

+ + #use_sslObject (readonly) + + + + + +

+
+ +

Returns the value of attribute use_ssl.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Config/config.rb', line 14
+
+def use_ssl
+  @use_ssl
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #read_allObject + + + + + +

+
+ +

Function to map all properties read from config file to variables

+ + +
+
+
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+
+
# File 'lib/juno/Config/config.rb', line 33
+
+def read_all
+  @response_timeout = @config.get_property(Juno::Properties::RESPONSE_TIMEOUT,
+                                           Juno::DefaultProperties::RESPONSE_TIMEOUT_MS)
+  @connection_timeout = @config.get_property(Juno::Properties::CONNECTION_TIMEOUT,
+                                             Juno::DefaultProperties::CONNECTION_TIMEOUT_MS)
+  @connection_pool_size = @config.get_property(Juno::Properties::CONNECTION_POOLSIZE,
+                                               Juno::DefaultProperties::CONNECTION_POOLSIZE)
+  @connection_lifetime = @config.get_property(Juno::Properties::CONNECTION_LIFETIME,
+                                              Juno::DefaultProperties::CONNECTION_LIFETIME_MS)
+  @default_lifetime = @config.get_property(Juno::Properties::DEFAULT_LIFETIME,
+                                           Juno::DefaultProperties::DEFAULT_LIFETIME_S)
+  @max_response_timeout = @config.get_property(Juno::Properties::MAX_RESPONSE_TIMEOUT,
+                                               Juno::DefaultProperties::MAX_RESPONSE_TIMEOUT_MS)
+  @max_connection_timeout = @config.get_property(Juno::Properties::MAX_CONNECTION_TIMEOUT,
+                                                 Juno::DefaultProperties::MAX_CONNECTION_TIMEOUT_MS)
+  @max_connection_pool_size = @config.get_property(Juno::Properties::MAX_CONNECTION_POOL_SIZE,
+                                                   Juno::DefaultProperties::MAX_CONNECTION_POOL_SIZE)
+  @max_connection_lifetime = @config.get_property(Juno::Properties::MAX_CONNECTION_LIFETIME,
+                                                  Juno::DefaultProperties::MAX_CONNECTION_LIFETIME_MS)
+  @max_lifetime = @config.get_property(Juno::Properties::MAX_LIFETIME, Juno::DefaultProperties::MAX_LIFETIME_S)
+  @max_key_size = @config.get_property(Juno::Properties::MAX_KEY_SIZE, Juno::DefaultProperties::MAX_KEY_SIZE_B)
+  @max_value_size = @config.get_property(Juno::Properties::MAX_VALUE_SIZE,
+                                         Juno::DefaultProperties::MAX_VALUE_SIZE_B)
+  @max_namespace_length = @config.get_property(Juno::Properties::MAX_NAMESPACE_LENGTH,
+                                               Juno::DefaultProperties::MAX_NAMESPACE_LENGTH)
+  @host = @config.get_property(Juno::Properties::HOST, Juno::DefaultProperties::HOST)
+  @port = @config.get_property(Juno::Properties::PORT, Juno::DefaultProperties::PORT)
+  @app_name = @config.get_property(Juno::Properties::APP_NAME, Juno::DefaultProperties::APP_NAME)
+  @record_namespace = @config.get_property(Juno::Properties::RECORD_NAMESPACE,
+                                           Juno::DefaultProperties::RECORD_NAMESPACE)
+  @use_ssl = @config.get_property(Juno::Properties::USE_SSL, Juno::DefaultProperties::USE_SSL)
+  @use_payload_compression = @config.get_property(Juno::Properties::USE_PAYLOAD_COMPRESSION,
+                                                  Juno::DefaultProperties::USE_PAYLOAD_COMPRESSION)
+  @operation_retry = @config.get_property(Juno::Properties::ENABLE_RETRY, Juno::DefaultProperties::OPERATION_RETRY)
+  @bypass_ltm = @config.get_property(Juno::Properties::BYPASS_LTM, Juno::DefaultProperties::BYPASS_LTM)
+  @reconnect_on_fail = @config.get_property(Juno::Properties::RECONNECT_ON_FAIL,
+                                            Juno::DefaultProperties::RECONNECT_ON_FAIL)
+  @config_prefix = @config.get_property(Juno::Properties::CONFIG_PREFIX, Juno::DefaultProperties::CONFIG_PREFIX)
+  nil
+end
+
+
+ +
+

+ + #validate!Object + + + + + +

+ + + + +
+
+
+
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+
+
# File 'lib/juno/Config/config.rb', line 74
+
+def validate!
+  missing_properties = []
+  REQUIRED_PROPERTIES.each do |property|
+    missing_properties.push(property) if send(property).nil?
+  end
+
+  if @use_ssl
+    %i[ssl_cert_file ssl_key_file].each do |property|
+      missing_properties.push(property) if send(property).nil?
+    end
+  end
+
+  if missing_properties.length.positive?
+    raise "Please provide a value for the required property(s) #{missing_properties.join(', ')}."
+  end
+
+  if @use_ssl
+    raise 'SSL Certificate file not found' unless File.exist?(@ssl_cert_file)
+    raise 'SSL Key file not found' unless File.exist?(@ssl_key_file)
+  end
+
+  nil
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Config/Source.html b/client/Ruby/docs/Juno/Config/Source.html new file mode 100644 index 00000000..a8cc3831 --- /dev/null +++ b/client/Ruby/docs/Juno/Config/Source.html @@ -0,0 +1,147 @@ + + + + + + + Class: Juno::Config::Source + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Config::Source + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/config.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
YAML_FILE = + +
+
0
+ +
JSON_FILE = + +
+
1
+ +
URL = + +
+
2
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/ConfigProvider.html b/client/Ruby/docs/Juno/ConfigProvider.html new file mode 100644 index 00000000..9115e800 --- /dev/null +++ b/client/Ruby/docs/Juno/ConfigProvider.html @@ -0,0 +1,603 @@ + + + + + + + Class: Juno::ConfigProvider + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::ConfigProvider + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/config_provider.rb
+
+ +
+ +

Overview

+
+ +

Class to read config from file or url

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(source_uri, source_format = nil, _http_handler = nil) ⇒ Object + + + + + +

+
+ +

Constructor

+ + +
+
+
+

Parameters:

+
    + +
  • + + source_uri + + + (URI) + + + + — +
    +

    Ruby URI Object for file or URL (required)

    +
    + +
  • + +
  • + + source_format + + + (String) + + + (defaults to: nil) + + + — +
    +

    source_format required only for url. Inferred from file extension when using file (optional)

    +
    + +
  • + +
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/juno/Config/config_provider.rb', line 12
+
+def initialize(source_uri, source_format = nil, _http_handler = nil)
+  begin
+    source_scheme = source_uri&.send(:scheme)
+  rescue StandardError => e
+    raise "Invalid source_uri object.\n #{e.message}"
+  end
+  if source_scheme == 'file'
+    read_from_file(source_uri)
+  elsif source_scheme =~ /^http(s)?$/
+    read_from_url(source_uri, source_format, http_handler)
+  else
+    raise 'Only local file and URL supported'
+  end
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #get_property(property_key, default_value = nil) ⇒ Object + + + + + +

+
+ +

Function to read propertied in the heirarchy define in Juno::Properties

+ + +
+
+
+

Parameters:

+
    + +
  • + + property_key + + + (String) + + + + — +
    +

    String key (required)

    +
    + +
  • + +
  • + + default_value + + + (optional) + + + (defaults to: nil) + + + — +
    +

    default value if property not found

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + + + + + +
    +

    Propert value. Returns default_value if property not found

    +
    + +
  • + +
+ +

See Also:

+ + +
+ + + + +
+
+
+
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+
+
# File 'lib/juno/Config/config_provider.rb', line 52
+
+def get_property(property_key, default_value = nil)
+  return default_value if property_key.to_s.empty?
+
+  value = configatron.to_h
+  property_key.to_s.split('.').each do |k|
+    return default_value unless value.is_a?(Hash) && value.key?(k.to_sym)
+
+    value = value[k.to_sym]
+    # puts "#{k} --- #{value}"
+  end
+
+  value.nil? || value.is_a?(Hash) ? default_value : value
+end
+
+
+ +
+

+ + #read_from_file(source_uri) ⇒ nil + + + + + +

+
+ +

Function to intialize configatron object from config file/URL

+ + +
+
+
+

Parameters:

+
    + +
  • + + source_uri + + + (URI) + + + + — +
    +

    Ruby URI Object for file or URL (required)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (nil) + + + +
  • + +
+ +
+ + + + +
+
+
+
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+
+
# File 'lib/juno/Config/config_provider.rb', line 30
+
+def read_from_file(source_uri)
+  raise 'Config file not found' unless File.exist?(source_uri.path)
+
+  hsh = if ['.yml', '.yaml'].include?(File.extname(source_uri.path))
+          YAML.load_file(source_uri.path)
+        elsif ['.json'].inlcude?(File.extname(source_uri.path))
+          json_text = File.read(source_uri.path)
+          JSON.parse(json_text)
+        else
+          raise 'Unknown file format'
+        end
+  configatron.configure_from_hash(hsh)
+  nil
+end
+
+
+ +
+

+ + #read_from_url(source_uri, source_format, http_handler) ⇒ Object + + + + + +

+ + + + +
+
+
+
+45
+
+
# File 'lib/juno/Config/config_provider.rb', line 45
+
+def read_from_url(source_uri, source_format, http_handler); end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/ConfigReader.html b/client/Ruby/docs/Juno/ConfigReader.html new file mode 100644 index 00000000..df1a4d19 --- /dev/null +++ b/client/Ruby/docs/Juno/ConfigReader.html @@ -0,0 +1,1002 @@ + + + + + + + Class: Juno::ConfigReader + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::ConfigReader + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/config_reader.rb
+
+ +
+ +

Overview

+
+ +

Properties Reader - Properties to be read from the developer using Juno.configure Either file_path or url is required log device can be a filename or IO Object

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #file_path ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute file_path.

    +
    + +
  • + + +
  • + + + #http_handler ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute http_handler.

    +
    + +
  • + + +
  • + + + #log_device ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute log_device.

    +
    + +
  • + + +
  • + + + #log_file ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute log_file.

    +
    + +
  • + + +
  • + + + #log_level ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute log_level.

    +
    + +
  • + + +
  • + + + #log_rotation ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute log_rotation.

    +
    + +
  • + + +
  • + + + #max_log_file_bytes ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute max_log_file_bytes.

    +
    + +
  • + + +
  • + + + #source_format ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute source_format.

    +
    + +
  • + + +
  • + + + #ssl_cert_file ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute ssl_cert_file.

    +
    + +
  • + + +
  • + + + #ssl_key_file ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute ssl_key_file.

    +
    + +
  • + + +
  • + + + #url ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute url.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeConfigReader + + + + + +

+
+ +

Returns a new instance of ConfigReader.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+18
+
+
# File 'lib/juno/Config/config_reader.rb', line 12
+
+def initialize
+  # default values
+  @log_level = ::Logger::Severity::INFO
+  @max_log_file_bytes = 1_048_576 # default for inbuilt logger class
+  @log_device = $stdout
+  @log_rotation = 'daily' # daily, weekly, monthly
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #file_pathObject + + + + + +

+
+ +

Returns the value of attribute file_path.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def file_path
+  @file_path
+end
+
+
+ + + +
+

+ + #http_handlerObject + + + + + +

+
+ +

Returns the value of attribute http_handler.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def http_handler
+  @http_handler
+end
+
+
+ + + +
+

+ + #log_deviceObject + + + + + +

+
+ +

Returns the value of attribute log_device.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def log_device
+  @log_device
+end
+
+
+ + + +
+

+ + #log_fileObject + + + + + +

+
+ +

Returns the value of attribute log_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def log_file
+  @log_file
+end
+
+
+ + + +
+

+ + #log_levelObject + + + + + +

+
+ +

Returns the value of attribute log_level.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def log_level
+  @log_level
+end
+
+
+ + + +
+

+ + #log_rotationObject + + + + + +

+
+ +

Returns the value of attribute log_rotation.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def log_rotation
+  @log_rotation
+end
+
+
+ + + +
+

+ + #max_log_file_bytesObject + + + + + +

+
+ +

Returns the value of attribute max_log_file_bytes.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def max_log_file_bytes
+  @max_log_file_bytes
+end
+
+
+ + + +
+

+ + #source_formatObject + + + + + +

+
+ +

Returns the value of attribute source_format.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def source_format
+  @source_format
+end
+
+
+ + + +
+

+ + #ssl_cert_fileObject + + + + + +

+
+ +

Returns the value of attribute ssl_cert_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def ssl_cert_file
+  @ssl_cert_file
+end
+
+
+ + + +
+

+ + #ssl_key_fileObject + + + + + +

+
+ +

Returns the value of attribute ssl_key_file.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def ssl_key_file
+  @ssl_key_file
+end
+
+
+ + + +
+

+ + #urlObject + + + + + +

+
+ +

Returns the value of attribute url.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/Config/config_reader.rb', line 9
+
+def url
+  @url
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/DefaultProperties.html b/client/Ruby/docs/Juno/DefaultProperties.html new file mode 100644 index 00000000..be59348d --- /dev/null +++ b/client/Ruby/docs/Juno/DefaultProperties.html @@ -0,0 +1,291 @@ + + + + + + + Class: Juno::DefaultProperties + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::DefaultProperties + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/default_properties.rb
+
+ +
+ +

Overview

+
+ +

Module containing constant default values for Properties

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
RESPONSE_TIMEOUT_MS = + +
+
200
+ +
CONNECTION_TIMEOUT_MS = + +
+
200
+ +
CONNECTION_POOLSIZE = + +
+
1
+ +
CONNECTION_LIFETIME_MS = + +
+
30_000
+ +
DEFAULT_LIFETIME_S = + +
+
259_200
+ +
MAX_RESPONSE_TIMEOUT_MS = +
+
+ +

Max for all above property

+ + +
+
+
+ + +
+
+
5000
+ +
MAX_CONNECTION_LIFETIME_MS = + +
+
30_000
+ +
MAX_CONNECTION_TIMEOUT_MS = + +
+
5000
+ +
MAX_KEY_SIZE_B = + +
+
128
+ +
MAX_VALUE_SIZE_B = + +
+
204_800
+ +
MAX_NAMESPACE_LENGTH = + +
+
64
+ +
MAX_CONNECTION_POOL_SIZE = + +
+
3
+ +
MAX_LIFETIME_S = + +
+
259_200
+ +
HOST = +
+
+ +

Required Properties

+ + +
+
+
+ + +
+
+
''
+ +
PORT = + +
+
0
+ +
APP_NAME = + +
+
''
+ +
RECORD_NAMESPACE = + +
+
''
+ +
CONFIG_PREFIX = +
+
+ +

optional Properties

+ + +
+
+
+ + +
+
+
''
+ +
USE_SSL = + +
+
true
+ +
RECONNECT_ON_FAIL = + +
+
false
+ +
USE_PAYLOAD_COMPRESSION = + +
+
false
+ +
OPERATION_RETRY = + +
+
false
+ +
BYPASS_LTM = + +
+
true
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO.html b/client/Ruby/docs/Juno/IO.html new file mode 100644 index 00000000..fbc7867d --- /dev/null +++ b/client/Ruby/docs/Juno/IO.html @@ -0,0 +1,227 @@ + + + + + + + Module: Juno::IO + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Juno::IO + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/constants.rb,
+ lib/juno/IO/JunoMessage.rb,
lib/juno/IO/ProtocolHeader.rb,
lib/juno/IO/OperationMessage.rb,
lib/juno/IO/PayloadComponent.rb,
lib/juno/IO/MetadataComponent.rb,
lib/juno/IO/MetadataComponentTemplate.rb
+
+
+ +
+ +

Overview

+
+ +

Juno wire protocol consists of a 12-byte header. Depending on the type, the appropriate message payload follows the fixed header section. Following is the header protocol:

+ +
      | 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7|
+ byte |                      0|                      1|                      2|                      3|
+------+-----------------------+-----------------------+-----------------------+-----------------------+
+    0 | magic                                         | version               | message type flag     |
+      |                                               |                       +-----------------+-----+
+      |                                               |                       | type            | RQ  |
+------+-----------------------------------------------+-----------------------+-----------------+-----+
+    4 | message size                                                                                  |
+------+-----------------------------------------------------------------------------------------------+
+    8 | opaque                                                                                        |
+------+-----------------------------------------------------------------------------------------------+
+
+ +

Following is the detailed description of each field in the header:

+ +

offset name size (bytes) meaning 0 Magic 2 Magic number, used to identify Juno message.

+ +

'0x5050'

+ +

2 Version 1 Protocol version, current version is 1. 3 Message Type flag

+ +
1 	bit 0-5
+
+ +

Message Type

+ +

0: Operational Message

+ +

1: Admin Message

+ +

2: Cluster Control Message

+ +

bit 6-7 RQ flag

+ +

0: response

+ +

1: two way request

+ +

3: one way request

+ +

4 Message size 4 Specifies the length of the message 8 Opaque 4 The Opaque data set in the request will be copied back in the response Operational Message Client Info (ip, port, type, application name) Request Type: request or response Operation Type: Create, Get, Update, Delete Request Id Request Info (key, ttl, version, namespace) Payload data size Payload Response Info (status/error code, error string) Flag Before defining the details of the protocol for operational message, we need to review, and finalize somethings at page.

+ +

Operational Message Header

+ +
operational request header
+      |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
+ byte |              0|              1|              2|              3|
+------+---------------+---------------+---------------+---------------+
+    0 | opcode        |flag           | shard Id                      |
+      |               +-+-------------+                               |
+      |               |R|             |                               |
+------+---------------+-+-------------+-------------------------------+
+
+operational response header
+      |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
+ byte |              0|              1|              2|              3|
+------+---------------+---------------+---------------+---------------+
+    0 | opcode        |flag           | reserved      | status        |
+      |               +-+-------------+               |               |
+      |               |R|             |               |               |
+------+---------------+-+-------------+---------------+---------------+
+
+opcode:
+  0x00    Nop
+  0x01    Create
+  0x02    Get
+  0x03    Update
+  0x04    Set
+  0x05    Destroy
+  0x81    PrepareCreate
+  0x82    Read
+  0x83    PrepareUpdate
+  0x84    PrepareSet
+  0x85    PrepareDelete
+  0x86    Delete
+  0xC1    Commit
+  0xC2    Abort (Rollback)
+  0xC3    Repair
+  0xC4    MarkDelete
+  0xE1    Clone
+  0xFE    MockSetParam
+  oxFF    MockReSet
+
+ +

R:

+ +
1 if it is for replication
+
+ +

shard Id:

+ +
only meaning for request to SS
+
+ +

status:

+ +
1 byte, only meaningful for response
+
+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: CompressionType, JunoMessage, MetadataComponent, MetadataComponentTemplate, OffsetWidth, OperationMessage, PayloadComponent, PayloadType, ProtocolHeader + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/CompressionType.html b/client/Ruby/docs/Juno/IO/CompressionType.html new file mode 100644 index 00000000..7ccc89ec --- /dev/null +++ b/client/Ruby/docs/Juno/IO/CompressionType.html @@ -0,0 +1,250 @@ + + + + + + + Class: Juno::IO::CompressionType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::CompressionType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/constants.rb
+
+ +
+ +

Overview

+
+ +

Class containing constants for CompressionType

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
None = + +
+
'None'
+ +
Snappy = + +
+
'Snappy'
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .valid?(compression_type) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/juno/IO/constants.rb', line 31
+
+def self.valid?(compression_type)
+  constants.each do |constant|
+    return true if const_get(constant) == compression_type
+  end
+  false
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/JunoMessage.html b/client/Ruby/docs/Juno/IO/JunoMessage.html new file mode 100644 index 00000000..7994ce10 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/JunoMessage.html @@ -0,0 +1,1860 @@ + + + + + + + Class: Juno::IO::JunoMessage + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::JunoMessage + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/JunoMessage.rb
+
+ +
+ +

Overview

+
+ +

JunoMessage containing all configuration required to create an operation message

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: OperationType + + +

+ + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeJunoMessage + + + + + +

+
+ +

Returns a new instance of JunoMessage.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 13
+
+def initialize
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @operation_type = Juno::IO::JunoMessage::OperationType::NOP
+  @server_status = Juno::ServerStatus::SUCCESS
+  @compression_type = Juno::IO::CompressionType::None
+  @is_compressed = false
+  @compression_achieved = 0
+  @message_size = 0
+  @value = ''
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #app_nameObject + + + + + +

+
+ +

Returns the value of attribute app_name.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def app_name
+  @app_name
+end
+
+
+ + + +
+

+ + #compression_achievedObject + + + + + +

+
+ +

Returns the value of attribute compression_achieved.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def compression_achieved
+  @compression_achieved
+end
+
+
+ + + +
+

+ + #compression_typeObject + + + + + +

+
+ +

Returns the value of attribute compression_type.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def compression_type
+  @compression_type
+end
+
+
+ + + +
+

+ + #correlation_idObject + + + + + +

+
+ +

Returns the value of attribute correlation_id.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def correlation_id
+  @correlation_id
+end
+
+
+ + + +
+

+ + #creation_timeObject + + + + + +

+
+ +

Returns the value of attribute creation_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def creation_time
+  @creation_time
+end
+
+
+ + + +
+

+ + #expiration_timeObject + + + + + +

+
+ +

Returns the value of attribute expiration_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def expiration_time
+  @expiration_time
+end
+
+
+ + + +
+

+ + #expiryObject + + + + + +

+
+ +

Returns the value of attribute expiry.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def expiry
+  @expiry
+end
+
+
+ + + +
+

+ + #ipObject + + + + + +

+
+ +

Returns the value of attribute ip.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def ip
+  @ip
+end
+
+
+ + + +
+

+ + #is_compressedObject + + + + + +

+
+ +

Returns the value of attribute is_compressed.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def is_compressed
+  @is_compressed
+end
+
+
+ + + +
+

+ + #keyObject + + + + + +

+
+ +

Returns the value of attribute key.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def key
+  @key
+end
+
+
+ + + +
+

+ + #last_modificationObject + + + + + +

+
+ +

Returns the value of attribute last_modification.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def last_modification
+  @last_modification
+end
+
+
+ + + +
+

+ + #message_sizeObject + + + + + +

+
+ +

Returns the value of attribute message_size.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def message_size
+  @message_size
+end
+
+
+ + + +
+

+ + #namespaceObject + + + + + +

+
+ +

Returns the value of attribute namespace.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def namespace
+  @namespace
+end
+
+
+ + + +
+

+ + #operation_typeObject + + + + + +

+
+ +

Returns the value of attribute operation_type.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def operation_type
+  @operation_type
+end
+
+
+ + + +
+

+ + #originator_request_idObject + + + + + +

+
+ +

Returns the value of attribute originator_request_id.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def originator_request_id
+  @originator_request_id
+end
+
+
+ + + +
+

+ + #portObject + + + + + +

+
+ +

Returns the value of attribute port.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def port
+  @port
+end
+
+
+ + + +
+

+ + #request_handling_timeObject + + + + + +

+
+ +

Returns the value of attribute request_handling_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def request_handling_time
+  @request_handling_time
+end
+
+
+ + + +
+

+ + #request_start_timeObject + + + + + +

+
+ +

Returns the value of attribute request_start_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def request_start_time
+  @request_start_time
+end
+
+
+ + + +
+

+ + #request_uuidObject + + + + + +

+
+ +

Returns the value of attribute request_uuid.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def request_uuid
+  @request_uuid
+end
+
+
+ + + +
+

+ + #server_statusObject + + + + + +

+
+ +

Returns the value of attribute server_status.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def server_status
+  @server_status
+end
+
+
+ + + +
+

+ + #time_to_live_sObject + + + + + +

+
+ +

Returns the value of attribute time_to_live_s.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def time_to_live_s
+  @time_to_live_s
+end
+
+
+ + + +
+

+ + #valueObject + + + + + +

+
+ +

Returns the value of attribute value.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def value
+  @value
+end
+
+
+ + + +
+

+ + #versionObject + + + + + +

+
+ +

Returns the value of attribute version.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 7
+
+def version
+  @version
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/JunoMessage/OperationType.html b/client/Ruby/docs/Juno/IO/JunoMessage/OperationType.html new file mode 100644 index 00000000..2b425508 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/JunoMessage/OperationType.html @@ -0,0 +1,304 @@ + + + + + + + Class: Juno::IO::JunoMessage::OperationType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::JunoMessage::OperationType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/JunoMessage.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
NOP = + +
+
0
+ +
CREATE = + +
+
1
+ +
GET = + +
+
2
+ +
UPDATE = + +
+
3
+ +
SET = + +
+
4
+ +
DESTROY = + +
+
5
+ +
@@status_code_map = + +
+
nil
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .get(status_code) ⇒ Object + + + + + +

+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 44
+
+def self.get(status_code)
+  initialize_map if @@status_code_map.nil?
+  return @@status_code_map[status_code.to_i] if @@status_code_map.key?(status_code)
+
+  INTERNAL_ERROR
+end
+
+
+ +
+

+ + .initialize_mapObject + + + + + +

+ + + + +
+
+
+
+35
+36
+37
+38
+39
+40
+41
+42
+
+
# File 'lib/juno/IO/JunoMessage.rb', line 35
+
+def self.initialize_map
+  @@status_code_map = {}
+
+  constants.each do |const|
+    const_obj = const_get(const)
+    @@status_code_map[const_obj.to_i] = const_obj
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponent.html b/client/Ruby/docs/Juno/IO/MetadataComponent.html new file mode 100644 index 00000000..affccc6a --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponent.html @@ -0,0 +1,2518 @@ + + + + + + + Class: Juno::IO::MetadataComponent + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponent + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponent.rb
+
+ +
+ +

Overview

+
+ +

Wrapper class for MetadataComponentTemplate

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: MetadataField, TagAndType + + +

+ + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #app_name ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute app_name.

    +
    + +
  • + + +
  • + + + #correlation_id ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute correlation_id.

    +
    + +
  • + + +
  • + + + #creation_time ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute creation_time.

    +
    + +
  • + + +
  • + + + #expiration_time ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute expiration_time.

    +
    + +
  • + + +
  • + + + #ip ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute ip.

    +
    + +
  • + + +
  • + + + #last_modification ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute last_modification.

    +
    + +
  • + + +
  • + + + #metadata_field_list ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute metadata_field_list.

    +
    + +
  • + + +
  • + + + #originator_request_id ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute originator_request_id.

    +
    + +
  • + + +
  • + + + #port ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute port.

    +
    + +
  • + + +
  • + + + #request_handling_time ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute request_handling_time.

    +
    + +
  • + + +
  • + + + #request_uuid ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute request_uuid.

    +
    + +
  • + + +
  • + + + #time_to_live ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute time_to_live.

    +
    + +
  • + + +
  • + + + #version ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    +

    Returns the value of attribute version.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeMetadataComponent + + + + + +

+
+ +

Returns a new instance of MetadataComponent.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+94
+95
+96
+97
+98
+99
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 94
+
+def initialize
+  @PROG_NAME = self.class.name
+  # @LOGGER = Juno::Logger.instance
+  # @metadata_field_list [Array<MetadataField>]
+  @metadata_field_list = []
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #app_nameObject (readonly) + + + + + +

+
+ +

Returns the value of attribute app_name.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def app_name
+  @app_name
+end
+
+
+ + + +
+

+ + #correlation_idObject (readonly) + + + + + +

+
+ +

Returns the value of attribute correlation_id.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def correlation_id
+  @correlation_id
+end
+
+
+ + + +
+

+ + #creation_timeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute creation_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def creation_time
+  @creation_time
+end
+
+
+ + + +
+

+ + #expiration_timeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute expiration_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def expiration_time
+  @expiration_time
+end
+
+
+ + + +
+

+ + #ipObject (readonly) + + + + + +

+
+ +

Returns the value of attribute ip.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def ip
+  @ip
+end
+
+
+ + + +
+

+ + #last_modificationObject (readonly) + + + + + +

+
+ +

Returns the value of attribute last_modification.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def last_modification
+  @last_modification
+end
+
+
+ + + +
+

+ + #metadata_field_listObject (readonly) + + + + + +

+
+ +

Returns the value of attribute metadata_field_list.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def 
+  @metadata_field_list
+end
+
+
+ + + +
+

+ + #originator_request_idObject (readonly) + + + + + +

+
+ +

Returns the value of attribute originator_request_id.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def originator_request_id
+  @originator_request_id
+end
+
+
+ + + +
+

+ + #portObject (readonly) + + + + + +

+
+ +

Returns the value of attribute port.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def port
+  @port
+end
+
+
+ + + +
+

+ + #request_handling_timeObject (readonly) + + + + + +

+
+ +

Returns the value of attribute request_handling_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def request_handling_time
+  @request_handling_time
+end
+
+
+ + + +
+

+ + #request_uuidObject (readonly) + + + + + +

+
+ +

Returns the value of attribute request_uuid.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def request_uuid
+  @request_uuid
+end
+
+
+ + + +
+

+ + #time_to_liveObject (readonly) + + + + + +

+
+ +

Returns the value of attribute time_to_live.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def time_to_live
+  @time_to_live
+end
+
+
+ + + +
+

+ + #versionObject (readonly) + + + + + +

+
+ +

Returns the value of attribute version.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+91
+92
+93
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 91
+
+def version
+  @version
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_field(field) ⇒ Object + + + + + +

+
+ +

Function to add feild to the list

+ + +
+
+
+

Parameters:

+
    + +
  • + + field + + + (MetadataField) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+202
+203
+204
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 202
+
+def add_field(field)
+  .push(field)
+end
+
+
+ +
+

+ + #num_bytesObject + + + + + +

+
+ +

function to calculate size of metadata component

+ + +
+
+
+ + +
+ + + + +
+
+
+
+207
+208
+209
+210
+211
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 207
+
+def num_bytes
+  io = StringIO.new
+  write(io)
+  io.size
+end
+
+
+ +
+

+ + #read(io) ⇒ Object + + + + + +

+
+ +

Function to de-serialize Component to buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + io + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 238
+
+def read(io)
+   = MetadataComponentTemplate.new
+  .read(io)
+
+  body_buffer = StringIO.new(.body)
+
+  ..each do |field|
+    case field.field_tag
+    when TagAndType::TimeToLive[:tag]
+      ttl_byte_string = body_buffer.read(1 << (1 + TagAndType::TimeToLive[:size_type]))
+      set_time_to_live(ttl_byte_string.unpack1(OffsetWidth.UINT32))
+
+    when TagAndType::Version[:tag]
+      version_byte_string = body_buffer.read(1 << (1 + TagAndType::Version[:size_type]))
+      set_version(version_byte_string.unpack1(OffsetWidth.UINT32))
+
+    when TagAndType::CreationTime[:tag]
+      creation_time_byte_string = body_buffer.read(1 << (1 + TagAndType::CreationTime[:size_type]))
+      set_creation_time(creation_time_byte_string.unpack1(OffsetWidth.UINT32))
+
+    when TagAndType::RequestUUID[:tag]
+      request_uuid_byte_string = body_buffer.read(1 << (1 + TagAndType::RequestUUID[:size_type]))
+      set_request_uuid(request_uuid_byte_string)
+
+    when TagAndType::SourceInfo[:tag]
+      source_info = MetadataComponentTemplate::SourceInfoField.new
+      source_info.read(body_buffer)
+      set_source_info(app_name: source_info.app_name, ip: IPAddr.new_ntoh(source_info.ip), port: source_info.port)
+
+    when TagAndType::LastModification[:tag]
+      last_modification_byte_string = body_buffer.read(1 << (1 + TagAndType::LastModification[:size_type]))
+      set_last_modification(last_modification_byte_string.unpack1(OffsetWidth.UINT64))
+
+    when TagAndType::ExpirationTime[:tag]
+      expiration_time_byte_string = body_buffer.read(1 << (1 + TagAndType::ExpirationTime[:size_type]))
+      set_expiration_time(expiration_time_byte_string.unpack1(OffsetWidth.UINT32))
+
+    when TagAndType::OriginatorRequestID[:tag]
+      originator_request_id_byte_string = body_buffer.read(1 << (1 + TagAndType::OriginatorRequestID[:size_type]))
+      set_originator_request_id(originator_request_id_byte_string)
+    # when TagAndType::CorrelationID[:tag]
+
+    when TagAndType::RequestHandlingTime[:tag]
+      request_handling_time_byte_string = body_buffer.read(1 << (1 + TagAndType::RequestHandlingTime[:size_type]))
+      set_request_handling_time(request_handling_time_byte_string.unpack1(OffsetWidth.UINT32))
+    end
+  end
+end
+
+
+ +
+

+ + #set_correlation_id(input_uuid_byte_string = nil) ⇒ Object + + + + + +

+
+ +

if not provided, creates a uuid itself

+ + +
+
+
+

Parameters:

+
    + +
  • + + input_uuid_byte_string + + + (String) + + + (defaults to: nil) + + + — +
    +

    (optional)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 180
+
+def set_correlation_id(input_uuid_byte_string = nil)
+  @correlation_id = if input_uuid_byte_string.nil?
+                      UUIDTools::UUID.random_create
+                    else
+                      UUIDTools::UUID.parse_raw(input_uuid_byte_string)
+                    end
+  field = MetadataComponentTemplate::CorrelationIDField.new
+  field.correlation_id = @correlation_id.raw
+  str_io = StringIO.new
+  field.write(str_io)
+  # puts field
+  add_field(MetadataField.new(0x09, 0x0, str_io.string))
+end
+
+
+ +
+

+ + #set_creation_time(data) ⇒ Object + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + creation_time + + + (Integer) + + + + — +
    • +

      Unix timestamp (required)

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+119
+120
+121
+122
+123
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 119
+
+def set_creation_time(data)
+  @creation_time = data
+  creation_time_bytes_string = [data].pack(OffsetWidth.UINT32)
+  add_field(MetadataField.new(0x03, 0x01, creation_time_bytes_string))
+end
+
+
+ +
+

+ + #set_expiration_time(data) ⇒ Object + + + + + +

+ + + + +
+
+
+
+125
+126
+127
+128
+129
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 125
+
+def set_expiration_time(data)
+  @expiration_time = data
+  expiration_time_bytes_string = [data].pack(OffsetWidth.UINT32)
+  add_field(MetadataField.new(0x04, 0x01, expiration_time_bytes_string))
+end
+
+
+ +
+

+ + #set_last_modification(data) ⇒ Object + + + + + +

+ + + + +
+
+
+
+160
+161
+162
+163
+164
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 160
+
+def set_last_modification(data)
+  @last_modification = data
+  last_modification_bytes_string = [data].pack(OffsetWidth.UINT64)
+  add_field(MetadataField.new(0x07, 0x02, last_modification_bytes_string))
+end
+
+
+ +
+

+ + #set_originator_request_id(input_uuid_byte_string = nil) ⇒ Object + + + + + +

+
+ +

if not provided, creates a uuid itself

+ + +
+
+
+

Parameters:

+
    + +
  • + + input_uuid_byte_string + + + (String) + + + (defaults to: nil) + + + — +
    +

    (optional)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+168
+169
+170
+171
+172
+173
+174
+175
+176
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 168
+
+def set_originator_request_id(input_uuid_byte_string = nil)
+  @originator_request_id = if input_uuid_byte_string.nil?
+                             UUIDTools::UUID.random_create
+                           else
+                             UUIDTools::UUID.parse_raw(input_uuid_byte_string)
+                           end
+  add_field(MetadataField.new(0x08, 0x03, @originator_request_id.raw))
+  @originator_request_id
+end
+
+
+ +
+

+ + #set_request_handling_time(data) ⇒ Object + + + + + +

+ + + + +
+
+
+
+194
+195
+196
+197
+198
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 194
+
+def set_request_handling_time(data)
+  @request_handling_time = data
+  request_handling_time_bytes_string = [data].pack(OffsetWidth.UINT32)
+  add_field(MetadataField.new(0x0A, 0x01, request_handling_time_bytes_string))
+end
+
+
+ +
+

+ + #set_request_uuid(input_uuid_byte_string = nil) ⇒ Object + + + + + +

+
+ +

if not provided, creates a uuid itself

+ + +
+
+
+

Parameters:

+
    + +
  • + + input_uuid_byte_string + + + (String) + + + (defaults to: nil) + + + — +
    • +

      Record Time to live (optional)

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+133
+134
+135
+136
+137
+138
+139
+140
+141
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 133
+
+def set_request_uuid(input_uuid_byte_string = nil)
+  @request_uuid = if input_uuid_byte_string.nil?
+                    UUIDTools::UUID.random_create
+                  else
+                    UUIDTools::UUID.parse_raw(input_uuid_byte_string)
+                  end
+  add_field(MetadataField.new(0x05, 0x03, @request_uuid.raw))
+  @request_uuid
+end
+
+
+ +
+

+ + #set_source_info(app_name:, ip:, port:) ⇒ Object + + + + + +

+
+ +

SourceInfoField

+ + +
+
+
+

Parameters:

+
    + +
  • + + app_name + + + (String) + + + + — +
    • +

      Record Time to live (required)

      +
    +
    + +
  • + +
  • + + ip + + + (IPAddr) + + + + — +
    • +

      ip address for component (required)

      +
    +
    + +
  • + +
  • + + port + + + (Integer) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 147
+
+def set_source_info(app_name:, ip:, port:)
+  @ip = ip
+  @port = port
+  @app_name = app_name
+  data = MetadataComponentTemplate::SourceInfoField.new
+  data.app_name = app_name
+  data.ip = ip.hton
+  data.port = port
+  str_io = StringIO.new
+  data.write(str_io)
+  add_field(MetadataField.new(0x06, 0x00, str_io.string))
+end
+
+
+ +
+

+ + #set_time_to_live(ttl) ⇒ Object + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + ttl + + + (Integer) + + + + — +
    • +

      Record Time to live

      +
    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+102
+103
+104
+105
+106
+107
+108
+109
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 102
+
+def set_time_to_live(ttl)
+  ttl = ttl.to_i
+  raise ArgumentError, 'TTL should be > 0' unless ttl.positive?
+
+  @time_to_live = ttl
+  ttl = [ttl].pack(OffsetWidth.UINT32)
+  add_field(MetadataField.new(0x01, 0x01, ttl))
+end
+
+
+ +
+

+ + #set_version(data) ⇒ Object + + + + + +

+
+ + +
+
+
+

Parameters:

+
    + +
  • + + version + + + (Integer) + + + + — +
    • +

      Record version

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+112
+113
+114
+115
+116
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 112
+
+def set_version(data)
+  @version = data
+  version_bytes_string = [data].pack(OffsetWidth.UINT32)
+  add_field(MetadataField.new(0x02, 0x01, version_bytes_string))
+end
+
+
+ +
+

+ + #write(io) ⇒ Object + + + + + +

+
+ +

Function to serialize Component to buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + io + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 215
+
+def write(io)
+  buffer = MetadataComponentTemplate.new
+  buffer.number_of_fields = .length
+  .each do |field|
+    f = MetadataComponentTemplate::MetadataHeaderField.new
+    f.size_type = field.size_type
+    f.field_tag = field.tag
+    buffer..push(f)
+  end
+
+  body = StringIO.new
+  .each do |field|
+    body.write(field.data)
+  end
+  padding_size = (8 - body.size % 8) % 8
+  body.write(Array.new(0, padding_size).pack(OffsetWidth.UINT8('*'))) if padding_size.positive?
+  buffer.body = body.string
+
+  buffer.write(io)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField.html b/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField.html new file mode 100644 index 00000000..7853e2ae --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField.html @@ -0,0 +1,514 @@ + + + + + + + Class: Juno::IO::MetadataComponent::MetadataField + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponent::MetadataField + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponent.rb
+
+ +
+ +

Overview

+
+ +

DataType for @metadata_field_list

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: SizeType + + +

+ + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #data ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute data.

    +
    + +
  • + + +
  • + + + #size_type ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute size_type.

    +
    + +
  • + + +
  • + + + #tag ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute tag.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(tag, size_type, data) ⇒ MetadataField + + + + + +

+
+ +

Returns a new instance of MetadataField.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+334
+335
+336
+337
+338
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 334
+
+def initialize(tag, size_type, data)
+  @tag = tag
+  @size_type = size_type
+  @data = data
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #dataObject + + + + + +

+
+ +

Returns the value of attribute data.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+332
+333
+334
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 332
+
+def data
+  @data
+end
+
+
+ + + +
+

+ + #size_typeObject + + + + + +

+
+ +

Returns the value of attribute size_type.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+332
+333
+334
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 332
+
+def size_type
+  @size_type
+end
+
+
+ + + +
+

+ + #tagObject + + + + + +

+
+ +

Returns the value of attribute tag.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+332
+333
+334
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 332
+
+def tag
+  @tag
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #sizeObject + + + + + +

+ + + + +
+
+
+
+340
+341
+342
+343
+344
+345
+346
+
+
# File 'lib/juno/IO/MetadataComponent.rb', line 340
+
+def size
+  if size_type == SizeType::Variable
+    data.length
+  else
+    1 << (size_type + 1)
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField/SizeType.html b/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField/SizeType.html new file mode 100644 index 00000000..a866f481 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponent/MetadataField/SizeType.html @@ -0,0 +1,137 @@ + + + + + + + Class: Juno::IO::MetadataComponent::MetadataField::SizeType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponent::MetadataField::SizeType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponent.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
Variable = + +
+
0
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponent/TagAndType.html b/client/Ruby/docs/Juno/IO/MetadataComponent/TagAndType.html new file mode 100644 index 00000000..bfa69384 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponent/TagAndType.html @@ -0,0 +1,212 @@ + + + + + + + Class: Juno::IO::MetadataComponent::TagAndType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponent::TagAndType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponent.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
TimeToLive = + +
+
{
+  tag: 0x01,
+  size_type: 0x01
+}.freeze
+ +
Version = + +
+
{
+  tag: 0x02,
+  size_type: 0x01
+}.freeze
+ +
CreationTime = + +
+
{
+  tag: 0x03,
+  size_type: 0x01
+}.freeze
+ +
RequestUUID = + +
+
{
+  tag: 0x05,
+  size_type: 0x03
+}.freeze
+ +
SourceInfo = + +
+
{
+  tag: 0x06,
+  size_type: 0x00
+}.freeze
+ +
ExpirationTime = + +
+
{
+  tag: 0x04,
+  size_type: 0x01
+}.freeze
+ +
LastModification = + +
+
{
+  tag: 0x07,
+  size_type: 0x02
+}.freeze
+ +
OriginatorRequestID = + +
+
{
+  tag: 0x08,
+  size_type: 0x03
+}.freeze
+ +
CorrelationID = + +
+
{
+  tag: 0x09,
+  size_type: 0x00
+}.freeze
+ +
RequestHandlingTime = + +
+
{
+  tag: 0x0A,
+  size_type: 0x01
+}.freeze
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponentTemplate.html b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate.html new file mode 100644 index 00000000..d1fb34ee --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate.html @@ -0,0 +1,255 @@ + + + + + + + Class: Juno::IO::MetadataComponentTemplate + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponentTemplate + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponentTemplate.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: CorrelationIDField, FixedLengthField, MetadataHeaderField, SourceInfoField + + +

+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #header_num_bytesObject + + + + + +

+ + + + +
+
+
+
+52
+53
+54
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 52
+
+def header_num_bytes
+  component_size.num_bytes + tag_id.num_bytes + number_of_fields.num_bytes + .num_bytes
+end
+
+
+ +
+

+ + #header_padding_lengthObject + + + + + +

+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 56
+
+def header_padding_length
+  (4 - header_num_bytes % 4) % 4
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/CorrelationIDField.html b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/CorrelationIDField.html new file mode 100644 index 00000000..ea32bd9b --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/CorrelationIDField.html @@ -0,0 +1,195 @@ + + + + + + + Class: Juno::IO::MetadataComponentTemplate::CorrelationIDField + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponentTemplate::CorrelationIDField + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponentTemplate.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #padding_sizeObject + + + + + +

+ + + + +
+
+
+
+40
+41
+42
+43
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 40
+
+def padding_size
+  size = component_size.num_bytes + correlation_id_length.num_bytes + correlation_id.num_bytes
+  (4 - size % 4) % 4
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/FixedLengthField.html b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/FixedLengthField.html new file mode 100644 index 00000000..0afbca92 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/FixedLengthField.html @@ -0,0 +1,124 @@ + + + + + + + Class: Juno::IO::MetadataComponentTemplate::FixedLengthField + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponentTemplate::FixedLengthField + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponentTemplate.rb
+
+ +
+ + + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/MetadataHeaderField.html b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/MetadataHeaderField.html new file mode 100644 index 00000000..b173ae2c --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/MetadataHeaderField.html @@ -0,0 +1,124 @@ + + + + + + + Class: Juno::IO::MetadataComponentTemplate::MetadataHeaderField + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponentTemplate::MetadataHeaderField + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponentTemplate.rb
+
+ +
+ + + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/SourceInfoField.html b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/SourceInfoField.html new file mode 100644 index 00000000..f1d8d8f0 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/MetadataComponentTemplate/SourceInfoField.html @@ -0,0 +1,319 @@ + + + + + + + Class: Juno::IO::MetadataComponentTemplate::SourceInfoField + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::MetadataComponentTemplate::SourceInfoField + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/MetadataComponentTemplate.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #field_bytesObject + + + + + +

+ + + + +
+
+
+
+18
+19
+20
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 18
+
+def field_bytes
+  field_length.num_bytes + app_name_length.num_bytes + port.num_bytes + ip.num_bytes + app_name.num_bytes
+end
+
+
+ +
+

+ + #ipv6?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+26
+27
+28
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 26
+
+def ipv6?
+  IPAddr.new_ntoh(ip).ipv6?
+end
+
+
+ +
+

+ + #padding_sizeObject + + + + + +

+ + + + +
+
+
+
+22
+23
+24
+
+
# File 'lib/juno/IO/MetadataComponentTemplate.rb', line 22
+
+def padding_size
+  (4 - field_bytes % 4) % 4
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/OffsetWidth.html b/client/Ruby/docs/Juno/IO/OffsetWidth.html new file mode 100644 index 00000000..9ac361ec --- /dev/null +++ b/client/Ruby/docs/Juno/IO/OffsetWidth.html @@ -0,0 +1,359 @@ + + + + + + + Class: Juno::IO::OffsetWidth + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::OffsetWidth + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/constants.rb
+
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .UINT16(count = '') ⇒ Object + + + + + +

+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/juno/IO/constants.rb', line 17
+
+def self.UINT16(count = '')
+  "n#{count}"
+end
+
+
+ +
+

+ + .UINT32(count = '') ⇒ Object + + + + + +

+ + + + +
+
+
+
+13
+14
+15
+
+
# File 'lib/juno/IO/constants.rb', line 13
+
+def self.UINT32(count = '')
+  "N#{count}"
+end
+
+
+ +
+

+ + .UINT64(count = '') ⇒ Object + + + + + +

+
+ +

Count can be integer or '*'

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/juno/IO/constants.rb', line 9
+
+def self.UINT64(count = '')
+  "Q#{count}"
+end
+
+
+ +
+

+ + .UINT8(count = '') ⇒ Object + + + + + +

+ + + + +
+
+
+
+21
+22
+23
+
+
# File 'lib/juno/IO/constants.rb', line 21
+
+def self.UINT8(count = '')
+  "C#{count}"
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/OperationMessage.html b/client/Ruby/docs/Juno/IO/OperationMessage.html new file mode 100644 index 00000000..8d770e3e --- /dev/null +++ b/client/Ruby/docs/Juno/IO/OperationMessage.html @@ -0,0 +1,716 @@ + + + + + + + Class: Juno::IO::OperationMessage + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::OperationMessage + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/OperationMessage.rb
+
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeOperationMessage + + + + + +

+
+ +

Returns a new instance of OperationMessage.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+8
+9
+10
+11
+12
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 8
+
+def initialize
+  @protocol_header = ProtocolHeader.new
+  @metadata_component = nil
+  @payload_component = nil
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #metadata_componentObject + + + + + +

+
+ +

Returns the value of attribute metadata_component.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 6
+
+def 
+  @metadata_component
+end
+
+
+ + + +
+

+ + #payload_componentObject + + + + + +

+
+ +

Returns the value of attribute payload_component.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 6
+
+def payload_component
+  @payload_component
+end
+
+
+ + + +
+

+ + #protocol_headerObject + + + + + +

+
+ +

Returns the value of attribute protocol_header.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 6
+
+def protocol_header
+  @protocol_header
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #read(io) ⇒ Object + + + + + +

+
+ +

Function to de-serialize message to buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + io + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 35
+
+def read(io)
+  return if io.eof? || (io.size - io.pos) < 16
+
+  @protocol_header = ProtocolHeader.new
+  @metadata_component = MetadataComponent.new
+  @payload_component = PayloadComponent.new
+
+  @protocol_header.read(io)
+
+  remaining_size = protocol_header.message_size - 16
+  prev_position = io.pos
+
+  @metadata_component.read(io) if !io.eof? && (io.size - io.pos) >= remaining_size
+
+  remaining_size -= (io.pos - prev_position)
+
+  @payload_component.read(io) if !io.eof? && (io.size - io.pos) >= remaining_size
+  nil
+end
+
+
+ +
+

+ + #sizeObject + + + + + +

+
+ +

Calculates size of message

+ + +
+
+
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 15
+
+def size
+  total_size = protocol_header.num_bytes
+  total_size += payload_component.num_bytes unless payload_component.nil?
+  total_size += .num_bytes unless .nil?
+  total_size
+end
+
+
+ +
+

+ + #write(io) ⇒ Object + + + + + +

+
+ +

Function to serialize message to buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + io + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/juno/IO/OperationMessage.rb', line 24
+
+def write(io)
+  protocol_header.message_size = size
+
+  protocol_header.write(io)
+  &.write(io)
+  payload_component&.write(io)
+  nil
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/PayloadComponent.html b/client/Ruby/docs/Juno/IO/PayloadComponent.html new file mode 100644 index 00000000..65b84664 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/PayloadComponent.html @@ -0,0 +1,648 @@ + + + + + + + Class: Juno::IO::PayloadComponent + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::PayloadComponent + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/PayloadComponent.rb
+
+ +
+ +

Overview

+
+ +

** Payload (or KeyValue) Component **

+ +

A 12-byte header followed by name, key and value

+ +
Tag/ID: 0x01
+
+
  • +

    Header *

    + +
    |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
    +|              0|              1|              2|              3|
    +
    +
+ +

——---------------—————---------------—————+

+ +
0 | Size                                                          |
+
+ +

——---------------—————-------------------------------

+ +
4 | Tag/ID (0x01) | namespace len | key length                    |
+
+ +

——---------------—————-------------------------------

+ +
8 | payload length                                                |
+
+ +

——---------------------------------------------------------------

+ +
(
+ The max namespace length: 255
+ payload length = 0 if len(payload data) = 0, otherwise,
+ payload length = 1 + len(payload data) = len(payload field)
+)
+
+
  • +

    Body *

    +
+ +

---------—–---------------————————-+ |namespace| key | payload field | Padding to align 8-byte | ---------—–---------------————————-+

+
  • +

    Payload field*

    +
+ +

---------------------————–+ | 1 byte payload type | Payload data | ---------------------————–+

+
  • +

    Payload Type

    +
+ +

0: payload data is the actual value passed from client user 1: payload data is encrypted by Juno client library, details not specified 2: payload data is encrypted by Juno proxy with AES-GCM. encryption key length is 256 bits 3: Payload data is compressed by Juno Client library.

+
  • +

    Payload data

    +
+ +

for payload type 2 --------------------------------—————----------------- | 4 bytes encryption key version | 12 bytes nonce | encrypted data | --------------------------------—————-----------------

+ +

for payload type 3 ---------------------------------——————---------------- | 1 byte size of compression type | compression type | compressed data| ---------------------------------——————----------------

+
  • +

    compression type

    +
+ +

1) snappy (default algorithm) 2) TBD

+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + + + Classes: CompressedPayloadData, EncryptedPayloadData, UncompressedPayloadData + + +

+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #compressed?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+154
+155
+156
+157
+158
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 154
+
+def compressed?
+  return true if payload_type == PayloadType::Compressed
+
+  false
+end
+
+
+ +
+

+ + #compression_typeObject + + + + + +

+ + + + +
+
+
+
+160
+161
+162
+163
+164
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 160
+
+def compression_type
+  return payload_data.compression_type if compressed?
+
+  CompressionType::None
+end
+
+
+ +
+

+ + #custom_num_bytesObject + + + + + +

+
+ +

to prevent stack overflow

+ + +
+
+
+ + +
+ + + + +
+
+
+
+103
+104
+105
+106
+107
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 103
+
+def custom_num_bytes
+  size = component_size.num_bytes + tag_id.num_bytes + namespace_length.num_bytes + key_length.num_bytes + payload_length.num_bytes + namespace.num_bytes + payload_key.num_bytes
+  size += payload_type.num_bytes + payload_data.num_bytes if payload_length.positive?
+  size
+end
+
+
+ +
+

+ + #get_payload_data_lengthObject + + + + + +

+ + + + +
+
+
+
+98
+99
+100
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 98
+
+def get_payload_data_length
+  (payload_length.positive? ? payload_length - 1 : 0)
+end
+
+
+ +
+

+ + #padding_lengthObject + + + + + +

+ + + + +
+
+
+
+109
+110
+111
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 109
+
+def padding_length
+  (8 - custom_num_bytes % 8) % 8
+end
+
+
+ +
+

+ + #set_value(input_value, compression_type = CompressionType::None) ⇒ Object + + + + + +

+ + + + +
+
+
+
+140
+141
+142
+143
+144
+145
+146
+147
+148
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 140
+
+def set_value(input_value, compression_type = CompressionType::None)
+  if compression_type != CompressionType::None
+    self.payload_type = PayloadType::Compressed
+    payload_data.compression_type = compression_type
+  else
+    self.payload_type = PayloadType::UnCompressed
+  end
+  payload_data.data = input_value
+end
+
+
+ +
+

+ + #valueObject + + + + + +

+ + + + +
+
+
+
+150
+151
+152
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 150
+
+def value
+  payload_data.data
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/PayloadComponent/CompressedPayloadData.html b/client/Ruby/docs/Juno/IO/PayloadComponent/CompressedPayloadData.html new file mode 100644 index 00000000..8f58a9d8 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/PayloadComponent/CompressedPayloadData.html @@ -0,0 +1,193 @@ + + + + + + + Class: Juno::IO::PayloadComponent::CompressedPayloadData + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::PayloadComponent::CompressedPayloadData + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/PayloadComponent.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #data_lengthObject + + + + + +

+ + + + +
+
+
+
+65
+66
+67
+
+
# File 'lib/juno/IO/PayloadComponent.rb', line 65
+
+def data_length
+  eval_parameter(:payload_data_length) - 1 - compression_type
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/PayloadComponent/EncryptedPayloadData.html b/client/Ruby/docs/Juno/IO/PayloadComponent/EncryptedPayloadData.html new file mode 100644 index 00000000..f2bb7e08 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/PayloadComponent/EncryptedPayloadData.html @@ -0,0 +1,124 @@ + + + + + + + Class: Juno::IO::PayloadComponent::EncryptedPayloadData + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::PayloadComponent::EncryptedPayloadData + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/PayloadComponent.rb
+
+ +
+ + + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/PayloadComponent/UncompressedPayloadData.html b/client/Ruby/docs/Juno/IO/PayloadComponent/UncompressedPayloadData.html new file mode 100644 index 00000000..68f9f00c --- /dev/null +++ b/client/Ruby/docs/Juno/IO/PayloadComponent/UncompressedPayloadData.html @@ -0,0 +1,142 @@ + + + + + + + Class: Juno::IO::PayloadComponent::UncompressedPayloadData + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::PayloadComponent::UncompressedPayloadData + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/PayloadComponent.rb
+
+ +
+ +

Overview

+
+ +

encrypted_payload_data PayloadType::Encrypted, payload_data_length: lambda {

+ +
                                                                        get_payload_data_length
+                                                                      }
+end
+
+ +

end

+ + +
+
+
+ + +
+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/PayloadType.html b/client/Ruby/docs/Juno/IO/PayloadType.html new file mode 100644 index 00000000..e620dfe5 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/PayloadType.html @@ -0,0 +1,158 @@ + + + + + + + Class: Juno::IO::PayloadType + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::PayloadType + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/constants.rb
+
+ +
+ +

Overview

+
+ +

Class containing constants for PayloadType

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
UnCompressed = + +
+
0x00
+ +
Encrypted = + +
+
0x02
+ +
Compressed = + +
+
0x03
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/ProtocolHeader.html b/client/Ruby/docs/Juno/IO/ProtocolHeader.html new file mode 100644 index 00000000..5a973178 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/ProtocolHeader.html @@ -0,0 +1,329 @@ + + + + + + + Class: Juno::IO::ProtocolHeader + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::ProtocolHeader + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/ProtocolHeader.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: MessageTypeFlag, MessageTypes, OpCodes, RequestTypes + + +

+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Instance Method Details

+ + +
+

+ + #message_typeObject + + + + + +

+ + + + +
+
+
+
+176
+177
+178
+
+
# File 'lib/juno/IO/ProtocolHeader.rb', line 176
+
+def message_type
+  message_type_flag.message_type
+end
+
+
+ +
+

+ + #request?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+155
+156
+157
+
+
# File 'lib/juno/IO/ProtocolHeader.rb', line 155
+
+def request?
+  message_type_flag.message_request_type != RequestTypes::Response
+end
+
+
+ +
+

+ + #request_typeObject + + + + + +

+ + + + +
+
+
+
+172
+173
+174
+
+
# File 'lib/juno/IO/ProtocolHeader.rb', line 172
+
+def request_type
+  message_type_flag.message_request_type
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypeFlag.html b/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypeFlag.html new file mode 100644 index 00000000..0063eb4e --- /dev/null +++ b/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypeFlag.html @@ -0,0 +1,124 @@ + + + + + + + Class: Juno::IO::ProtocolHeader::MessageTypeFlag + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::ProtocolHeader::MessageTypeFlag + + + +

+
+ +
+
Inherits:
+
+ BinData::Record + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/ProtocolHeader.rb
+
+ +
+ + + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypes.html b/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypes.html new file mode 100644 index 00000000..8c1bf0b9 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/ProtocolHeader/MessageTypes.html @@ -0,0 +1,147 @@ + + + + + + + Class: Juno::IO::ProtocolHeader::MessageTypes + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::ProtocolHeader::MessageTypes + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/ProtocolHeader.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
OperationalMessage = + +
+
0
+ +
AdminMessage = + +
+
1
+ +
ClusterControlMessage = + +
+
2
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/ProtocolHeader/OpCodes.html b/client/Ruby/docs/Juno/IO/ProtocolHeader/OpCodes.html new file mode 100644 index 00000000..59fe3e80 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/ProtocolHeader/OpCodes.html @@ -0,0 +1,324 @@ + + + + + + + Class: Juno::IO::ProtocolHeader::OpCodes + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::ProtocolHeader::OpCodes + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/ProtocolHeader.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
Nop = + +
+
0x00
+ +
Create = + +
+
0x01
+ +
Get = + +
+
0x02
+ +
Update = + +
+
0x03
+ +
Set = + +
+
0x04
+ +
Destroy = + +
+
0x05
+ +
PrepareCreate = + +
+
0x81
+ +
Read = + +
+
0x82
+ +
PrepareUpdate = + +
+
0x83
+ +
PrepareSet = + +
+
0x84
+ +
PrepareDelete = + +
+
0x85
+ +
Delete = + +
+
0x86
+ +
Commit = + +
+
0xC1
+ +
Abort = + +
+
0xC2
+ +
Repair = + +
+
0xC3
+ +
MarkDelete = + +
+
0xC4
+ +
Clone = + +
+
0xE1
+ +
MockSetParam = + +
+
0xFE
+ +
MockReSet = + +
+
0xFF
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .valid?(opcode) ⇒ Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+142
+143
+144
+145
+146
+147
+
+
# File 'lib/juno/IO/ProtocolHeader.rb', line 142
+
+def self.valid?(opcode)
+  constants.each do |constant|
+    return true if const_get(constant) == opcode
+  end
+  false
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/IO/ProtocolHeader/RequestTypes.html b/client/Ruby/docs/Juno/IO/ProtocolHeader/RequestTypes.html new file mode 100644 index 00000000..d414bbf7 --- /dev/null +++ b/client/Ruby/docs/Juno/IO/ProtocolHeader/RequestTypes.html @@ -0,0 +1,147 @@ + + + + + + + Class: Juno::IO::ProtocolHeader::RequestTypes + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::IO::ProtocolHeader::RequestTypes + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/IO/ProtocolHeader.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
Response = + +
+
0
+ +
TwoWayRequest = + +
+
1
+ +
OneWayRequest = + +
+
2
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Logger.html b/client/Ruby/docs/Juno/Logger.html new file mode 100644 index 00000000..fee07851 --- /dev/null +++ b/client/Ruby/docs/Juno/Logger.html @@ -0,0 +1,307 @@ + + + + + + + Class: Juno::Logger + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Logger + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/logger.rb
+
+ +
+ +

Overview

+
+ +

DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
@@mutex = + +
+
Mutex.new
+ +
@@instance = +
+
+ +

Singleton instance

+ + +
+
+
+ + +
+
+
nil
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .instanceObject + + + + + +

+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/juno/logger.rb', line 12
+
+def self.instance
+  return @@instance unless @@instance.nil?
+
+  @@mutex.synchronize do
+    if @@instance.nil?
+      raise 'log file not configured' if Juno.juno_config.log_file.to_s.empty?
+
+      @@instance = ::Logger.new(Juno.juno_config.log_file, 'daily', progname: 'JunoRubyClient')
+
+      @@instance.level = ::Logger::INFO
+    end
+  end
+  @@instance
+end
+
+
+ +
+

+ + .level=(log_level) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/juno/logger.rb', line 27
+
+def self.level=(log_level)
+  @@instance.level = log_level unless @@instance.nil?
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net.html b/client/Ruby/docs/Juno/Net.html new file mode 100644 index 00000000..d9786d61 --- /dev/null +++ b/client/Ruby/docs/Juno/Net.html @@ -0,0 +1,117 @@ + + + + + + + Module: Juno::Net + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Juno::Net + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/worker_pool.rb,
+ lib/juno/Net/io_processor.rb,
lib/juno/Net/ping_message.rb,
lib/juno/Net/request_queue.rb,
lib/juno/Net/base_processor.rb,
lib/juno/Net/client_handler.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: BaseProcessor, ClientHandler, IOProcessor, PingMessage, QueueEntry, RequestQueue, WorkerPool + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/BaseProcessor.html b/client/Ruby/docs/Juno/Net/BaseProcessor.html new file mode 100644 index 00000000..f7a608b8 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/BaseProcessor.html @@ -0,0 +1,404 @@ + + + + + + + Class: Juno::Net::BaseProcessor + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::BaseProcessor + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/base_processor.rb
+
+ +
+ +

Overview

+
+ +

BaseProcessor - base class for IOProcessor Handles logic for reading and writing ping_ip for bypass ltm

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

IOProcessor

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(_ = nil) ⇒ BaseProcessor + + + + + +

+
+ +

Returns a new instance of BaseProcessor.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/juno/Net/base_processor.rb', line 8
+
+def initialize(_ = nil)
+  @ping_queue = SizedQueue.new(1)
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #clear_ping_queueObject + + + + + +

+ + + + +
+
+
+
+32
+33
+34
+
+
# File 'lib/juno/Net/base_processor.rb', line 32
+
+def clear_ping_queue
+  @ping_queue.clear
+end
+
+
+ +
+

+ + #ping_ipObject + + + + + +

+ + + + +
+
+
+
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
+
# File 'lib/juno/Net/base_processor.rb', line 16
+
+def ping_ip
+  begin
+    ip = @ping_queue.pop(true)
+  rescue ThreadError
+    return nil
+  end
+
+  return nil if ip.to_s.empty?
+
+  begin
+    IPAddr.new(ip)
+  rescue StandardError
+    nil
+  end
+end
+
+
+ +
+

+ + #ping_ip=(ip) ⇒ Object + + + + + +

+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/juno/Net/base_processor.rb', line 12
+
+def ping_ip=(ip)
+  @ping_queue.push(ip)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/ClientHandler.html b/client/Ruby/docs/Juno/Net/ClientHandler.html new file mode 100644 index 00000000..bebd3697 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/ClientHandler.html @@ -0,0 +1,1143 @@ + + + + + + + Class: Juno::Net::ClientHandler + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::ClientHandler + + + +

+
+ +
+
Inherits:
+
+ EventMachine::Connection + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/client_handler.rb
+
+ +
+ +

Overview

+
+ +

Hanldes connection creation and receiving data asynchronously Managed by EventMachine::Connection

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
@@recv_count = +
+
+ +

Constant to count messages received

+ + +
+
+
+ + +
+
+
Concurrent::AtomicFixnum.new(0)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(io_processor) ⇒ ClientHandler + + + + + +

+
+ +

Constructor

+ + +
+
+
+

Parameters:

+ + + +
+ + + + +
+
+
+
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/juno/Net/client_handler.rb', line 17
+
+def initialize(io_processor)
+  super
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @io_processor = io_processor
+  @channel = self
+  @connected = Concurrent::AtomicBoolean.new(false)
+  @ssl_connected = Concurrent::AtomicBoolean.new(false)
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .received_messagesObject + + + + + +

+ + + + +
+
+
+
+11
+12
+13
+
+
# File 'lib/juno/Net/client_handler.rb', line 11
+
+def self.received_messages
+  @@recv_count.value
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #connection_completedObject + + + + + +

+
+ +

Called by EventMachine after TCP Connection estabilished

+ + +
+
+
+ + +
+ + + + +
+
+
+
+92
+93
+94
+95
+
+
# File 'lib/juno/Net/client_handler.rb', line 92
+
+def connection_completed
+  @connected.value = true
+  on_connection_completed unless use_ssl?
+end
+
+
+ +
+

+ + #is_connected?Boolean + + + + + +

+
+ +

method to check if channel is connected

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+
+
# File 'lib/juno/Net/client_handler.rb', line 55
+
+def is_connected?
+  if use_ssl?
+    return false if @ssl_connected.false?
+  elsif @connected.false?
+    return false
+  end
+
+  # get ip and port of server
+  # Socket.unpack_sockaddr_in(@channel.get_peername)
+  true
+rescue Exception => e
+  @LOGGER.error(@PROG_NAME) { e.message }
+  false
+end
+
+
+ +
+

+ + #on_connection_completedObject + + + + + +

+
+ +

Method called when TCP connection estabilished. If useSSL is true, it is called after a successfull ssl handshake

+ + +
+
+
+ + +
+ + + + +
+
+
+
+50
+51
+52
+
+
# File 'lib/juno/Net/client_handler.rb', line 50
+
+def on_connection_completed
+  # puts "completed #{Time.now}"
+end
+
+
+ +
+

+ + #post_initObject + + + + + +

+
+ +

Method called once for each instance of Juno::Net::ClientHandler at initialization

+ + +
+
+
+ + +
+ + + + +
+
+
+
+28
+29
+30
+
+
# File 'lib/juno/Net/client_handler.rb', line 28
+
+def post_init
+  start_tls_connection if use_ssl?
+end
+
+
+ +
+

+ + #receive_data(data) ⇒ Object + + + + + +

+
+ +

method called by EventMachine when data is received from server

+ + +
+
+
+

Parameters:

+
    + +
  • + + data + + + (String) + + + + — +
    • +

      byte data received from server

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+
+
# File 'lib/juno/Net/client_handler.rb', line 80
+
+def receive_data(data)
+  @@recv_count.increment
+  # puts @@recv_count
+
+  EventMachine.defer do
+    operation_message = Juno::IO::OperationMessage.new
+    operation_message.read(StringIO.new(data))
+    @io_processor.put_response(operation_message)
+  end
+end
+
+
+ +
+

+ + #ssl_handshake_completedObject + + + + + +

+
+ +

Called by EventMachine after ssl handshake

+ + +
+
+
+ + +
+ + + + +
+
+
+
+106
+107
+108
+109
+110
+111
+112
+113
+
+
# File 'lib/juno/Net/client_handler.rb', line 106
+
+def ssl_handshake_completed
+  @ssl_connected.value = true
+  on_connection_completed if use_ssl?
+
+  # puts get_cipher_name
+  # puts get_cipher_protocol
+  @server_handshake_completed = true
+end
+
+
+ +
+

+ + #start_tls_connectionObject + + + + + +

+
+ +

starts tls connection once TCP connection is estabilished

+ + +
+
+
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+
+
# File 'lib/juno/Net/client_handler.rb', line 33
+
+def start_tls_connection
+  raise 'SSL Cert file not found' unless File.exist?(Juno.juno_config.ssl_cert_file)
+  raise 'SSL Key file not found' unless File.exist?(Juno.juno_config.ssl_key_file)
+
+  @channel.start_tls(
+    private_key_file: Juno.juno_config.ssl_key_file, cert: File.read(Juno.juno_config.ssl_cert_file)
+  )
+  # Timer to check if SSL Handshake was successful
+  EventMachine::Timer.new(Juno.juno_config.max_connection_timeout.to_f / 1000) do
+    if @ssl_connected.false?
+      puts 'SLL Handshake timeout'
+      close_connection
+    end
+  end
+end
+
+
+ +
+

+ + #unbind(error) ⇒ Object + + + + + +

+
+ +

Called by EventMachine after connection disconnected

+ + +
+
+
+

Parameters:

+
    + +
  • + + m + + + + + + + — +
    • +

      Error if disconnected due to an error

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+99
+100
+101
+102
+103
+
+
# File 'lib/juno/Net/client_handler.rb', line 99
+
+def unbind(error)
+  @connected.value = false
+  @ssl_connected.value = false
+  puts error unless error.nil?
+end
+
+
+ +
+

+ + #use_ltm?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'lib/juno/Net/client_handler.rb', line 74
+
+def use_ltm?
+  Juno.juno_config.bypass_ltm
+end
+
+
+ +
+

+ + #use_ssl?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+70
+71
+72
+
+
# File 'lib/juno/Net/client_handler.rb', line 70
+
+def use_ssl?
+  Juno.juno_config.use_ssl
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/IOProcessor.html b/client/Ruby/docs/Juno/Net/IOProcessor.html new file mode 100644 index 00000000..8201fc68 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/IOProcessor.html @@ -0,0 +1,1536 @@ + + + + + + + Class: Juno::Net::IOProcessor + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::IOProcessor + + + +

+
+ +
+
Inherits:
+
+ BaseProcessor + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/io_processor.rb
+
+ +
+ +

Overview

+
+ +

Module to handle connections to server, reading/writing requests from request queue

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
INITIAL_BYPASSLTM_RETRY_INTERVAL = + +
+
337_500
+ +
MAX_BYPASSLTM_RETRY_INTERVAL = + +
+
86_400_000
+ +
INIT_WAIT_TIME = + +
+
200
+ +
MAX_WAIT_TIME = + +
+
60_000
+ +
@@counter = +
+
+ +

class variable to count messages sent using send_data

+ + +
+
+
+ + +
+
+
Concurrent::AtomicFixnum.new(0)
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseProcessor

+

#clear_ping_queue, #ping_ip, #ping_ip=

+
+

Constructor Details

+ +
+

+ + #initialize(request_queue, opaque_resp_queue_map) ⇒ IOProcessor + + + + + +

+
+ +

Returns a new instance of IOProcessor.

+ + +
+
+
+

Parameters:

+
    + +
  • + + request_queue + + + (Juno::Net::RequestQueue) + + + +
  • + +
  • + + opaque_resp_queue_map + + + (Concurrent::Map) + + + + — +
    • +

      map containing opaque as key and value as Response queue corresponding to opaque

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/juno/Net/io_processor.rb', line 20
+
+def initialize(request_queue, opaque_resp_queue_map)
+  super()
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @stop = false
+  @request_queue = request_queue
+  @opaque_resp_queue_map = opaque_resp_queue_map
+  @ctx = nil ## changed
+  @handshake_failed_attempts = 0
+  @reconnect_wait_time = INIT_WAIT_TIME
+  @shift = 5 # seconds
+  @next_bypass_ltm_check_time = Time.now
+  @bypass_ltm_retry_interval = INITIAL_BYPASSLTM_RETRY_INTERVAL
+  # @config = config
+  @channel = nil
+  @next_reconnect_due = Float::INFINITY
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .send_countObject + + + + + +

+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/juno/Net/io_processor.rb', line 14
+
+def self.send_count
+  @@counter.value
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #bypass_ltm_disabled?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+202
+203
+204
+205
+206
+207
+208
+
+
# File 'lib/juno/Net/io_processor.rb', line 202
+
+def bypass_ltm_disabled?
+  if Time.now > @next_bypass_ltm_check_time && @bypass_ltm_retry_interval < MAX_BYPASSLTM_RETRY_INTERVAL
+    return false
+  end
+
+  true
+end
+
+
+ +
+

+ + #connection_lifetimeObject + + + + + +

+ + + + +
+
+
+
+38
+39
+40
+
+
# File 'lib/juno/Net/io_processor.rb', line 38
+
+def connection_lifetime
+  Juno.juno_config.connection_lifetime
+end
+
+
+ +
+

+ + #disconnect_channel(channel) ⇒ Object + + + + + +

+ + + + +
+
+
+
+63
+64
+65
+66
+67
+
+
# File 'lib/juno/Net/io_processor.rb', line 63
+
+def disconnect_channel(channel)
+  EventMachine::Timer.new(2 * Juno.juno_config.max_response_timeout.to_f / 1000) do
+    channel&.close_connection_after_writing if !channel.nil? && channel.is_connected?
+  end
+end
+
+
+ +
+

+ + #hostObject + + + + + +

+ + + + +
+
+
+
+190
+191
+192
+
+
# File 'lib/juno/Net/io_processor.rb', line 190
+
+def host
+  Juno.juno_config.host
+end
+
+
+ +
+

+ + #initiate_bypass_ltmObject + + + + + +

+ + + + +
+
+
+
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+
+
# File 'lib/juno/Net/io_processor.rb', line 75
+
+def initiate_bypass_ltm
+  send_ping_message
+  EventMachine::Timer.new(Juno.juno_config.response_timeout.to_f / 1000) do
+    ip = ping_ip
+    unless ip.nil?
+      new_channel = EventMachine.connect(ip.to_s, Juno.juno_config.port, ClientHandler, self)
+      EventMachine::Timer.new(Juno.juno_config.connection_timeout.to_f / 1000) do
+        if new_channel.is_connected?
+          @LOGGER.info(@PROG_NAME) { "conncected to Proxy #{ip}:#{Juno.juno_config.port} " }
+          old_channel = @channel
+          @channel = new_channel
+          disconnect_channel(old_channel)
+        else
+          @LOGGER.info(@PROG_NAME) { "could not conncect to Proxy #{ip}:#{Juno.juno_config.port} " }
+        end
+      end
+    end
+  end
+end
+
+
+ +
+

+ + #juno_connect(recycle = false) ⇒ Object + + + + + +

+
+ +

Method to handle connections creation, re-attempts on failure, initiates connection refresh and connection to Proxy

+ + +
+
+
+

Parameters:

+
    + +
  • + + recycle + + + (Boolean) + + + (defaults to: false) + + + — +
    • +

      True if connection refresh request (optional, default: false)

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+
+
# File 'lib/juno/Net/io_processor.rb', line 107
+
+def juno_connect(recycle = false)
+  return if !recycle && !@channel.nil? && @channel.is_connected?
+
+  new_channel = EventMachine.connect(Juno.juno_config.host, Juno.juno_config.port, ClientHandler, self)
+  new_channel.pending_connect_timeout = Juno.juno_config.connection_lifetime
+  EventMachine::Timer.new(Juno.juno_config.connection_timeout.to_f / 1000) do
+    if new_channel.is_connected?
+      @LOGGER.info(@PROG_NAME) { "conncected to #{Juno.juno_config.host}:#{Juno.juno_config.port} " }
+      if recycle
+        old_channel = @channel
+        @channel = new_channel
+        disconnect_channel(old_channel)
+      else
+        @channel = new_channel
+      end
+      initiate_bypass_ltm if use_ltm?
+      set_recycle_timer
+    else
+      @recycle_timer&.cancel
+      new_channel&.close_connection if !new_channel.nil? && new_channel.is_connected?
+      @LOGGER.info(@PROG_NAME) do
+        "Could not conncect to #{Juno.juno_config.host}:#{Juno.juno_config.port}\n Retrying in #{@reconnect_wait_time.to_f / 1000}ms "
+      end
+      EventMachine::Timer.new(@reconnect_wait_time.to_f / 1000) do
+        @reconnect_wait_time *= 2
+        @reconnect_wait_time = MAX_WAIT_TIME if @reconnect_wait_time > MAX_WAIT_TIME
+        @reconnect_wait_time *= (1 + 0.3 * rand)
+        juno_connect(recycle)
+      end
+    end
+  end
+end
+
+
+ +
+

+ + #portObject + + + + + +

+ + + + +
+
+
+
+194
+195
+196
+
+
# File 'lib/juno/Net/io_processor.rb', line 194
+
+def port
+  Juno.juno_config.port
+end
+
+
+ +
+

+ + #put_response(operation_message) ⇒ Object + + + + + +

+ + + + +
+
+
+
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+
+
# File 'lib/juno/Net/io_processor.rb', line 42
+
+def put_response(operation_message)
+  return if operation_message.nil?
+
+  unless Juno::Net::PingMessage.ping_response?(operation_message, self)
+    opaque = operation_message&.protocol_header&.opaque
+    return if opaque.nil?
+
+    resp_queue = @opaque_resp_queue_map.get_and_set(opaque.to_i, nil)
+    if !resp_queue.nil?
+      begin
+        resp_queue.push(operation_message)
+      rescue ThreadError
+        @LOGGER.debug(@PROG_NAME) { "response queue for #{opaque.to_i} is full" }
+      end
+    else
+      @LOGGER.debug(@PROG_NAME) { "resp_queue nil for #{opaque.to_i}" }
+    end
+  end
+  nil
+end
+
+
+ +
+

+ + #reset_connectionsObject + + + + + +

+ + + + +
+
+
+
+181
+182
+183
+184
+
+
# File 'lib/juno/Net/io_processor.rb', line 181
+
+def reset_connections
+  @recycle_timer&.cancel
+  disconnect_channel(@channel)
+end
+
+
+ +
+

+ + #runObject + + + + + +

+
+ +

Event loop to continously check for requests in @request_queue

+ + +
+
+
+ + +
+ + + + +
+
+
+
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+
+
# File 'lib/juno/Net/io_processor.rb', line 145
+
+def run
+  EventMachine.run do
+    juno_connect
+    EventMachine.tick_loop do
+      if !@channel.nil? && @channel.is_connected?
+        # key = "19key#{rand(100) + rand(1_000_000)}"
+        item = @request_queue.pop
+        unless item.nil?
+          @@counter.increment
+          @channel.send_data(item.msg_buffer)
+        end
+      end
+      :stop if @stop == true
+    rescue Exception => e
+      @LOGGER.error(@PROG_NAME) do
+        "Error in tick_loop: #{e.message}. Stopping tick_loop"
+      end
+      :stop
+    end.on_stop do
+      @LOGGER.debug(@PROG_NAME) do
+        "tick loop stopped. Stop initiated by client #{@stop}"
+      end
+      reset_connections
+      EventMachine::Timer.new(2 * Juno.juno_config.connection_timeout.to_f / 1000) do
+        EventMachine.stop
+      end
+    end
+  rescue Exception => e
+    @LOGGER.debug(@PROG_NAME) do
+      "EventMachine Fatal Exception #{e.message}"
+    end
+    reset_connections
+    EventMachine.stop
+  end
+end
+
+
+ +
+

+ + #send_ping_messageObject + + + + + +

+
+ +

Sends ping message to LoadBalancer to get ProxyIP

+ + +
+
+
+ + +

See Also:

+ + +
+ + + + +
+
+
+
+97
+98
+99
+100
+101
+102
+103
+
+
# File 'lib/juno/Net/io_processor.rb', line 97
+
+def send_ping_message
+  ping_message = Juno::Net::PingMessage.new
+  buff = StringIO.new
+  ping_message.write(buff)
+  request_uuid = ping_message&.operation_message&.&.request_uuid.to_s
+  @request_queue.push(buff.string, request_uuid)
+end
+
+
+ +
+

+ + #set_recycle_timerObject + + + + + +

+ + + + +
+
+
+
+69
+70
+71
+72
+73
+
+
# File 'lib/juno/Net/io_processor.rb', line 69
+
+def set_recycle_timer
+  @recycle_timer = EventMachine::Timer.new(Juno.juno_config.connection_lifetime.to_f / 1000) do
+    juno_connect(true)
+  end
+end
+
+
+ +
+

+ + #stopObject + + + + + +

+ + + + +
+
+
+
+140
+141
+142
+
+
# File 'lib/juno/Net/io_processor.rb', line 140
+
+def stop
+  @stop = true
+end
+
+
+ +
+

+ + #use_ltm?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+198
+199
+200
+
+
# File 'lib/juno/Net/io_processor.rb', line 198
+
+def use_ltm?
+  host != '127.0.0.1' && Juno.juno_config.bypass_ltm # boolean
+end
+
+
+ +
+

+ + #use_ssl?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+186
+187
+188
+
+
# File 'lib/juno/Net/io_processor.rb', line 186
+
+def use_ssl?
+  Juno.juno_config.use_ssl
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/PingMessage.html b/client/Ruby/docs/Juno/Net/PingMessage.html new file mode 100644 index 00000000..13ea3377 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/PingMessage.html @@ -0,0 +1,864 @@ + + + + + + + Class: Juno::Net::PingMessage + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::PingMessage + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/ping_message.rb
+
+ +
+ +

Overview

+
+ +

Module to Create/Decode Ping messages

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
JUNO_INTERNAL_APPNAME = +
+
+ +

Constant Internal app name to check for ping messages

+ + +
+
+
+ + +
+
+
'JunoInternal'
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(app_name = nil, opaque = 0) ⇒ PingMessage + + + + + +

+
+ +

Returns a new instance of PingMessage.

+ + +
+
+
+

Parameters:

+
    + +
  • + + operation_message + + + (Juno::IO::OperationMessage) + + + + — +
    +

    (optional, default: Juno::Net::PingMessage::JUNO_INTERNAL_APPNAME)

    +
    + +
  • + +
  • + + opaque + + + (Integer) + + + (defaults to: 0) + + + — +
    +

    (optional, default: 0)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/juno/Net/ping_message.rb', line 15
+
+def initialize(app_name = nil, opaque = 0)
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  app_name = JUNO_INTERNAL_APPNAME if app_name.to_s.empty?
+
+   = Juno::IO::MetadataComponent.new
+  .set_request_uuid
+  .set_source_info(app_name: app_name, ip: IPAddr.new(Juno::Utils.local_ips[0]), port: 0)
+
+  protocol_header = Juno::IO::ProtocolHeader.new
+  protocol_header.opcode = Juno::IO::ProtocolHeader::OpCodes::Nop
+  protocol_header.opaque = opaque
+
+  @operation_message = Juno::IO::OperationMessage.new
+  @operation_message. = 
+  @operation_message.protocol_header = protocol_header
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #operation_messageObject (readonly) + + + + + +

+
+ +

method to read the operation message

+ + +
+
+
+ + +
+ + + + +
+
+
+
+11
+12
+13
+
+
# File 'lib/juno/Net/ping_message.rb', line 11
+
+def operation_message
+  @operation_message
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .ping_response?(operation_message, processor) ⇒ Boolean + + + + + +

+
+ +

method to check if given operation message is a Ping response Updates ping_ip in processor if it is a ping response

+ + +
+
+
+

Parameters:

+ + +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+
+
# File 'lib/juno/Net/ping_message.rb', line 37
+
+def self.ping_response?(operation_message, processor)
+  return false unless processor.use_ltm?
+
+  opcode = operation_message&.protocol_header&.opcode
+  raise 'missing protocol header' if opcode.nil?
+  return false if opcode != Juno::IO::ProtocolHeader::OpCodes::Nop
+  return false if operation_message&..nil?
+  return false if operation_message&.&.ip.to_s.empty?
+  return false if operation_message&.&.app_name != JUNO_INTERNAL_APPNAME
+
+  ping_ip = operation_message..ip.to_s
+  if ping_ip.split('.')[0] == '127'
+    processor.ping_ip = ''
+    return true
+  end
+  if Juno::Utils.local_ips.include?(ping_ip)
+    processor.ping_ip = ''
+    return true
+  end
+  processor.ping_ip = ping_ip
+  true
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #ipObject + + + + + +

+
+ +

Function to read the ping ip

+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'lib/juno/Net/ping_message.rb', line 74
+
+def ip
+  @operation_message&.&.ip
+end
+
+
+ +
+

+ + #portObject + + + + + +

+
+ +

Function to read the port from metadata component

+ + +
+
+
+ + +
+ + + + +
+
+
+
+79
+80
+81
+
+
# File 'lib/juno/Net/ping_message.rb', line 79
+
+def port
+  @operation_message&.&.port
+end
+
+
+ +
+

+ + #read(buf) ⇒ Object + + + + + +

+
+ +

Function to de-serialize Component from buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + buff + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+68
+69
+70
+71
+
+
# File 'lib/juno/Net/ping_message.rb', line 68
+
+def read(buf)
+  @operation_message = Juno::IO::OperationMessage.new
+  @operation_message.read(buf)
+end
+
+
+ +
+

+ + #write(buf) ⇒ Object + + + + + +

+
+ +

Function to serialize Component to buffer

+ + +
+
+
+

Parameters:

+
    + +
  • + + buff + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+62
+63
+64
+
+
# File 'lib/juno/Net/ping_message.rb', line 62
+
+def write(buf)
+  @operation_message.write(buf)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/QueueEntry.html b/client/Ruby/docs/Juno/Net/QueueEntry.html new file mode 100644 index 00000000..849f02e9 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/QueueEntry.html @@ -0,0 +1,475 @@ + + + + + + + Class: Juno::Net::QueueEntry + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::QueueEntry + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/request_queue.rb
+
+ +
+ +

Overview

+
+ +

DataType of each item in RequestQueue

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #enqueue_time ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute enqueue_time.

    +
    + +
  • + + +
  • + + + #msg_buffer ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute msg_buffer.

    +
    + +
  • + + +
  • + + + #req_id ⇒ Object + + + + + + + + + + + + + + + + +
    +

    Returns the value of attribute req_id.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(msg_buffer, id) ⇒ QueueEntry + + + + + +

+
+ +

Returns a new instance of QueueEntry.

+ + +
+
+
+

Parameters:

+
    + +
  • + + msg_bugger + + + (StringIO) + + + + — +
    +

    (required)

    +
    + +
  • + +
  • + + id + + + (String) + + + + — +
    • +

      request UUID (required)

      +
    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+11
+12
+13
+14
+15
+
+
# File 'lib/juno/Net/request_queue.rb', line 11
+
+def initialize(msg_buffer, id)
+  @msg_buffer = msg_buffer
+  @req_id = id
+  @enqueue_time = Time.now
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #enqueue_timeObject + + + + + +

+
+ +

Returns the value of attribute enqueue_time.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Net/request_queue.rb', line 7
+
+def enqueue_time
+  @enqueue_time
+end
+
+
+ + + +
+

+ + #msg_bufferObject + + + + + +

+
+ +

Returns the value of attribute msg_buffer.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Net/request_queue.rb', line 7
+
+def msg_buffer
+  @msg_buffer
+end
+
+
+ + + +
+

+ + #req_idObject + + + + + +

+
+ +

Returns the value of attribute req_id.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/juno/Net/request_queue.rb', line 7
+
+def req_id
+  @req_id
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/RequestQueue.html b/client/Ruby/docs/Juno/Net/RequestQueue.html new file mode 100644 index 00000000..8bec3653 --- /dev/null +++ b/client/Ruby/docs/Juno/Net/RequestQueue.html @@ -0,0 +1,826 @@ + + + + + + + Class: Juno::Net::RequestQueue + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::RequestQueue + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/request_queue.rb
+
+ +
+ +

Overview

+
+ +

Request queue - Singleton

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
@@mutex = +
+
+ +

mutex to synchronize creation of RequestQueue instance

+ + +
+
+
+ + +
+
+
Mutex.new
+ +
@@instance = +
+
+ +

Singleton instance

+ + +
+
+
+ + +
+
+
nil
+ +
+ + + + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeRequestQueue + + + + + +

+
+ +

Returns a new instance of RequestQueue.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/juno/Net/request_queue.rb', line 38
+
+def initialize
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @size = 13_000 # Default request queue size
+  @request_queue = SizedQueue.new(@size)
+  @opaque_resp_queue_map = Concurrent::Map.new
+  @worker_pool = Juno::Net::WorkerPool.new(self)
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #opaque_resp_queue_mapObject (readonly) + + + + + +

+
+ +

Returns the value of attribute opaque_resp_queue_map.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+36
+37
+38
+
+
# File 'lib/juno/Net/request_queue.rb', line 36
+
+def opaque_resp_queue_map
+  @opaque_resp_queue_map
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .instanceObject + + + + + +

+ + + + +
+
+
+
+26
+27
+28
+29
+30
+31
+32
+
+
# File 'lib/juno/Net/request_queue.rb', line 26
+
+def self.instance
+  return @@instance unless @@instance.nil?
+
+  @@mutex.synchronize do
+    @@instance ||= new
+  end
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #full?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+47
+48
+49
+
+
# File 'lib/juno/Net/request_queue.rb', line 47
+
+def full?
+  @request_queue.size == @size
+end
+
+
+ +
+

+ + #popQueueEntry + + + + + +

+
+ +

Returns - nil if queue empty.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (QueueEntry) + + + + — +
    • +

      nil if queue empty

      +
    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+80
+81
+82
+
+
# File 'lib/juno/Net/request_queue.rb', line 77
+
+def pop
+  @request_queue.pop(true)
+rescue ThreadError
+  # queue empty
+  nil
+end
+
+
+ +
+

+ + #push(msg_buffer, request_uuid) ⇒ Boolean + + + + + +

+
+ +

Returns - true if successfully pushed item to queue. Else false.

+ + +
+
+
+

Parameters:

+
    + +
  • + + operation_message + + + (Juno::IO::OperatioinMessage) + + + + — +
    +

    (required)

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +
    • +

      true if successfully pushed item to queue. Else false

      +
    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+
+
# File 'lib/juno/Net/request_queue.rb', line 62
+
+def push(msg_buffer, request_uuid)
+  # buffer = StringIO.new
+  # operation_message.write(buffer)
+  # request_uuid = operation_message&.metadata_component&.request_uuid.to_s
+  request_uuid = 'not_set' if request_uuid.to_s.empty?
+
+  begin
+    @request_queue.push(QueueEntry.new(msg_buffer, request_uuid), true)
+  rescue ThreadError
+    return false
+  end
+  true
+end
+
+
+ +
+

+ + #sizeObject + + + + + +

+ + + + +
+
+
+
+51
+52
+53
+
+
# File 'lib/juno/Net/request_queue.rb', line 51
+
+def size
+  @request_queue.size
+end
+
+
+ +
+

+ + #stopObject + + + + + +

+ + + + +
+
+
+
+55
+56
+57
+58
+
+
# File 'lib/juno/Net/request_queue.rb', line 55
+
+def stop
+  @worker_pool.stop
+  @request_queue.clear
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Net/WorkerPool.html b/client/Ruby/docs/Juno/Net/WorkerPool.html new file mode 100644 index 00000000..7c85a5ae --- /dev/null +++ b/client/Ruby/docs/Juno/Net/WorkerPool.html @@ -0,0 +1,405 @@ + + + + + + + Class: Juno::Net::WorkerPool + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Net::WorkerPool + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Net/worker_pool.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(request_queue) ⇒ WorkerPool + + + + + +

+
+ +

Returns a new instance of WorkerPool.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+
+
# File 'lib/juno/Net/worker_pool.rb', line 6
+
+def initialize(request_queue)
+  raise 'Request queue cannot be nil' if request_queue.nil?
+
+  @PROG_NAME = self.class.name
+  @LOGGER = Juno::Logger.instance
+  @request_queue = request_queue
+  EventMachine.threadpool_size = 200
+  @io_processor = Juno::Net::IOProcessor.new(@request_queue, @request_queue.opaque_resp_queue_map)
+  init
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #active?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+23
+24
+25
+
+
# File 'lib/juno/Net/worker_pool.rb', line 23
+
+def active?
+  @worker.alive?
+end
+
+
+ +
+

+ + #initObject + + + + + +

+ + + + +
+
+
+
+17
+18
+19
+20
+21
+
+
# File 'lib/juno/Net/worker_pool.rb', line 17
+
+def init
+  @worker = Thread.new do
+    @io_processor.run
+  end
+end
+
+
+ +
+

+ + #stopObject + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/juno/Net/worker_pool.rb', line 27
+
+def stop
+  @io_processor.stop
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Properties.html b/client/Ruby/docs/Juno/Properties.html new file mode 100644 index 00000000..96f382db --- /dev/null +++ b/client/Ruby/docs/Juno/Properties.html @@ -0,0 +1,269 @@ + + + + + + + Class: Juno::Properties + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Properties + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Config/properties.rb
+
+ +
+ +

Overview

+
+ +

Module for properties key (config file)

+ + +
+
+
+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
RESPONSE_TIMEOUT = + +
+
'juno.response.timeout_msec'
+ +
CONNECTION_TIMEOUT = + +
+
'juno.connection.timeout_msec'
+ +
DEFAULT_LIFETIME = + +
+
'juno.default_record_lifetime_sec'
+ +
CONNECTION_LIFETIME = + +
+
'juno.connection.recycle_duration_msec'
+ +
CONNECTION_POOLSIZE = + +
+
'juno.connection.pool_size'
+ +
RECONNECT_ON_FAIL = + +
+
'juno.connection.reconnect_on_fail'
+ +
HOST = + +
+
'juno.server.host'
+ +
PORT = + +
+
'juno.server.port'
+ +
APP_NAME = + +
+
'juno.application_name'
+ +
RECORD_NAMESPACE = + +
+
'juno.record_namespace'
+ +
USE_SSL = + +
+
'juno.useSSL'
+ +
USE_PAYLOAD_COMPRESSION = + +
+
'juno.usePayloadCompression'
+ +
ENABLE_RETRY = + +
+
'juno.operation.retry'
+ +
BYPASS_LTM = + +
+
'juno.connection.byPassLTM'
+ +
CONFIG_PREFIX = + +
+
'prefix'
+ +
MAX_LIFETIME = +
+
+ +

Max for each property

+ + +
+
+
+ + +
+
+
'juno.max_record_lifetime_sec'
+ +
MAX_KEY_SIZE = + +
+
'juno.max_key_size'
+ +
MAX_VALUE_SIZE = + +
+
'juno.max_value_size'
+ +
MAX_RESPONSE_TIMEOUT = + +
+
'juno.response.max_timeout_msec'
+ +
MAX_CONNECTION_TIMEOUT = + +
+
'juno.connection.max_timeout_msec'
+ +
MAX_CONNECTION_LIFETIME = + +
+
'juno.connection.max_recycle_duration_msec'
+ +
MAX_CONNECTION_POOL_SIZE = + +
+
'juno.connection.max_pool_size'
+ +
MAX_NAMESPACE_LENGTH = + +
+
'juno.max_record_namespace_length'
+ +
+ + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/ServerStatus.html b/client/Ruby/docs/Juno/ServerStatus.html new file mode 100644 index 00000000..d5da9619 --- /dev/null +++ b/client/Ruby/docs/Juno/ServerStatus.html @@ -0,0 +1,351 @@ + + + + + + + Class: Juno::ServerStatus + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::ServerStatus + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/server_status.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
SUCCESS = + +
+
{ code: 0, error_msg: 'no error', client_operation_status: Juno::Client::OperationStatus::SUCCESS }.freeze
+ +
BAD_MSG = + +
+
{ code: 1, error_msg: 'bad message',
+client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze
+ +
NO_KEY = + +
+
{ code: 3, error_msg: 'key not found',
+client_operation_status: Juno::Client::OperationStatus::NO_KEY }.freeze
+ +
DUP_KEY = + +
+
{ code: 4, error_msg: 'dup key',
+client_operation_status: Juno::Client::OperationStatus::UNIQUE_KEY_VIOLATION }.freeze
+ +
BAD_PARAM = + +
+
{ code: 7,  error_msg: 'bad parameter',
+client_operation_status: Juno::Client::OperationStatus::BAD_PARAM }.freeze
+ +
RECORD_LOCKED = + +
+
{ code: 8, error_msg: 'record locked',
+client_operation_status: Juno::Client::OperationStatus::RECORD_LOCKED }.freeze
+ +
NO_STORAGE_SERVER = + +
+
{ code: 12, error_msg: 'no active storage server',
+client_operation_status: Juno::Client::OperationStatus::NO_STORAGE }.freeze
+ +
SERVER_BUSY = + +
+
{ code: 14, error_msg: 'Server busy',
+client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze
+ +
VERSION_CONFLICT = + +
+
{ code: 19, error_msg:  'version conflict',
+client_operation_status: Juno::Client::OperationStatus::CONDITION_VIOLATION }.freeze
+ +
OP_STATUS_SS_READ_TTL_EXTENDERR = + +
+
{ code: 23, error_msg: 'Error extending TTL by SS',
+client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze
+ +
COMMIT_FAILURE = + +
+
{ code: 25, error_msg: 'Commit Failure',
+client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze
+ +
INCONSISTENT_STATE = + +
+
{ code: 26, error_msg: 'Inconsistent State',
+client_operation_status: Juno::Client::OperationStatus::SUCCESS }.freeze
+ +
INTERNAL = + +
+
{ code: 255, error_msg: 'Internal error',
+client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze
+ +
@@status_code_map = + +
+
nil
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .get(status_code) ⇒ Object + + + + + +

+ + + + +
+
+
+
+42
+43
+44
+45
+46
+47
+
+
# File 'lib/juno/server_status.rb', line 42
+
+def self.get(status_code)
+  initialize_map if @@status_code_map.nil?
+  return @@status_code_map[status_code] if @@status_code_map.key?(status_code.to_i)
+
+  INTERNAL
+end
+
+
+ +
+

+ + .initialize_mapObject + + + + + +

+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+
+
# File 'lib/juno/server_status.rb', line 33
+
+def self.initialize_map
+  @@status_code_map = {}
+
+  constants.each do |const|
+    const_obj = const_get(const)
+    @@status_code_map[const_obj[:code].to_i] = const_obj
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/Juno/Utils.html b/client/Ruby/docs/Juno/Utils.html new file mode 100644 index 00000000..35fced58 --- /dev/null +++ b/client/Ruby/docs/Juno/Utils.html @@ -0,0 +1,640 @@ + + + + + + + Class: Juno::Utils + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Juno::Utils + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/juno/Utils/utils.rb
+
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .create_and_send_ping_messageObject + + + + + +

+ + + + +
+
+
+
+110
+111
+112
+113
+114
+115
+116
+117
+118
+
+
# File 'lib/juno/Utils/utils.rb', line 110
+
+def self.create_and_send_ping_message
+  ping_message = Juno::Net::PingMessage.new
+  ping_buffer = StringIO.new
+  ping_message.write(ping_buffer)
+  response = ssl_request(ping_buffer)
+  ping_message = Juno::Net::PingMessage.new
+  ping_message.read(response)
+  ping_message
+end
+
+
+ +
+

+ + .create_message(key, op_type, value = '') ⇒ Object + + + + + +

+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+
+
# File 'lib/juno/Utils/utils.rb', line 15
+
+def self.create_message(key, op_type, value = '')
+   = Juno::IO::MetadataComponent.new
+  # ip = IPAddr.new(Socket.ip_address_list.detect(&:ipv4_private?).ip_address)
+  .set_time_to_live(Juno.juno_config.default_lifetime)
+  .set_version(1)
+  .set_creation_time(1000)
+  .set_request_uuid
+  .set_correlation_id
+  .set_originator_request_id
+  .set_source_info(app_name: Juno.juno_config.app_name, ip: IPAddr.new(Juno::Utils.local_ips[0]),
+                                      port: Juno.juno_config.port)
+
+  payload_component = Juno::IO::PayloadComponent.new
+  payload_component.namespace = Juno.juno_config.record_namespace
+  payload_component.payload_key = key
+  if op_type == Juno::IO::ProtocolHeader::OpCodes::Create && !value.to_s.empty?
+    is_compressed = false
+    if Juno.juno_config.use_payload_compression && value.length > 1024
+      value, compression_achieved = compressed_value(value)
+      is_compressed = true if compression_achieved.positive?
+    end
+    if is_compressed
+      puts 'using compression'
+      payload_component.set_value(value, Juno::IO::CompressionType::Snappy)
+    else
+      payload_component.set_value(value)
+    end
+  end
+
+  protocol_header = Juno::IO::ProtocolHeader.new
+  protocol_header.opcode = op_type
+
+  operation_message = Juno::IO::OperationMessage.new
+  operation_message. = 
+  operation_message.protocol_header = protocol_header
+  operation_message.payload_component = payload_component
+  buffer = StringIO.new
+  operation_message.write(buffer)
+  buffer
+end
+
+
+ +
+

+ + .local_ipsObject + + + + + +

+ + + + +
+
+
+
+5
+6
+7
+8
+9
+10
+11
+12
+13
+
+
# File 'lib/juno/Utils/utils.rb', line 5
+
+def self.local_ips
+  ip_addresses = Socket.ip_address_list.select do |addr|
+    addr.ipv4? && !addr.ipv4_loopback? # && !addr.ipv4_private?
+  end
+  ip_addresses.map!(&:ip_address)
+rescue StandardError => e
+  puts e.message
+  ['127.0.0.1']
+end
+
+
+ +
+

+ + .ssl_contextObject + + + + + +

+ + + + +
+
+
+
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+
+
# File 'lib/juno/Utils/utils.rb', line 56
+
+def self.ssl_context
+  ssl_context = OpenSSL::SSL::SSLContext.new
+  ssl_context.ssl_version = :TLSv1_1
+  cert = OpenSSL::X509::Certificate.new(File.open(File.expand_path(File.join(
+                                                                     __dir__, '..', '..', 'server.crt'
+                                                                   ))))
+  key = OpenSSL::PKey::RSA.new(File.open(File.expand_path(File.join(
+                                                            __dir__, '..', '..', 'server.pem'
+                                                          ))))
+  ca_file = OpenSSL::X509::Certificate.new(File.open(File.expand_path(File.join(
+                                                                        __dir__, '..', '..', 'myca.crt'
+                                                                      ))))
+  ssl_context.add_certificate(cert, key, [ca_file])
+  # ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
+  ssl_context.ssl_timeout = 10
+  ssl_context.timeout = 10
+  ssl_context
+end
+
+
+ +
+

+ + .ssl_request(buffer) ⇒ Object + + + + + +

+ + + + +
+
+
+
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+
+
# File 'lib/juno/Utils/utils.rb', line 75
+
+def self.ssl_request(buffer)
+  socket = TCPSocket.open(Juno.juno_config.host, Juno.juno_config.port)
+  if Juno.juno_config.use_ssl
+    ctx = ssl_context
+    socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
+    socket.sync_close = true
+    # socket.post_connection_check(Juno.juno_config.host)
+    socket.connect
+  end
+
+  # puts socket.peer_finished_message.bytes.join(', ')
+  # puts socket.verify_result
+
+  socket.write(buffer.string)
+  res_buffer = StringIO.new
+  header = true
+
+  size = 0
+  while (line = socket.sysread(1024 * 16)) # buffer size of OpenSSL library
+    if header
+      p = Juno::IO::ProtocolHeader.new
+      p.read(StringIO.new(line))
+      header = false
+      size = p.message_size
+    end
+    res_buffer.write(line)
+    break if res_buffer.length == size
+  end
+  socket.close
+
+  res_buffer.rewind
+
+  res_buffer
+end
+
+
+ +
+

+ + .time_diff_ms(a, b) ⇒ Object + + + + + +

+ + + + +
+
+
+
+120
+121
+122
+
+
# File 'lib/juno/Utils/utils.rb', line 120
+
+def self.time_diff_ms(a, b)
+  (b - a).abs * 1000
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/_index.html b/client/Ruby/docs/_index.html new file mode 100644 index 00000000..2c8e152e --- /dev/null +++ b/client/Ruby/docs/_index.html @@ -0,0 +1,620 @@ + + + + + + + Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
+ + +

Documentation by YARD 0.9.34

+
+

Alphabetic Index

+ +

File Listing

+ + +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + + + + + + + + + + + + + +
    +
  • F
  • + +
+ + +
    +
  • I
  • +
      + +
    • + IO + + (Juno) + +
    • + +
    • + IOProcessor + + (Juno::Net) + +
    • + +
    +
+ + + + + +
+ + +
    +
  • L
  • +
      + +
    • + Logger + + (Juno) + +
    • + +
    +
+ + + + + +
    +
  • N
  • +
      + +
    • + Net + + (Juno) + +
    • + +
    +
+ + + + + + + + +
    +
  • Q
  • + +
+ + + + + +
    +
  • S
  • + +
+ + +
+ + +
    +
  • T
  • +
      + +
    • + TagAndType + + (Juno::IO::MetadataComponent) + +
    • + +
    • + Type + + (Juno::Client::JunoRequest) + +
    • + +
    +
+ + + + + +
    +
  • W
  • + +
+ +
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/client/Ruby/docs/class_list.html b/client/Ruby/docs/class_list.html new file mode 100644 index 00000000..aac651f8 --- /dev/null +++ b/client/Ruby/docs/class_list.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + Class List + + + +
+
+

Class List

+ + + +
+ + +
+ + diff --git a/client/Ruby/docs/css/common.css b/client/Ruby/docs/css/common.css new file mode 100644 index 00000000..cf25c452 --- /dev/null +++ b/client/Ruby/docs/css/common.css @@ -0,0 +1 @@ +/* Override this file with custom rules */ \ No newline at end of file diff --git a/client/Ruby/docs/css/full_list.css b/client/Ruby/docs/css/full_list.css new file mode 100644 index 00000000..fa359824 --- /dev/null +++ b/client/Ruby/docs/css/full_list.css @@ -0,0 +1,58 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; + background: #fafafa; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } +#full_list ul { padding: 0; } +#full_list li { padding: 0; margin: 0; list-style: none; } +#full_list li .item { padding: 5px 5px 5px 12px; } +#noresults { padding: 7px 12px; background: #fff; } +#content.insearch #noresults { margin-left: 7px; } +li.collapsed ul { display: none; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } +li { color: #888; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.odd { background: #f0f0f0; } +li.even { background: #fafafa; } +.item:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a, a:visited { text-decoration: none; color: #05a; } +li.clicked > .item { background: #05a; color: #ccc; } +li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } +li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; border-radius: 3px; } +#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } +#full_list_nav a, #nav a:visited { color: #358; } +#full_list_nav a:hover { background: transparent; color: #5af; } +#full_list_nav span:after { content: ' | '; } +#full_list_nav span:last-child:after { content: ''; } + +#content h1 { margin-top: 0; } +li { white-space: nowrap; cursor: normal; } +li small { display: block; font-size: 0.8em; } +li small:before { content: ""; } +li small:after { content: ""; } +li small.search_info { display: none; } +#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } +#content.insearch #search { background-position: center right; } +#search input { width: 110px; } + +#full_list.insearch ul { display: block; } +#full_list.insearch .item { display: none; } +#full_list.insearch .found { display: block; padding-left: 11px !important; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/client/Ruby/docs/css/style.css b/client/Ruby/docs/css/style.css new file mode 100644 index 00000000..eb0dbc86 --- /dev/null +++ b/client/Ruby/docs/css/style.css @@ -0,0 +1,497 @@ +html { + width: 100%; + height: 100%; +} +body { + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + width: 100%; + margin: 0; + padding: 0; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} + +#nav { + position: relative; + width: 100%; + height: 100%; + border: 0; + border-right: 1px dotted #eee; + overflow: auto; +} +.nav_wrap { + margin: 0; + padding: 0; + width: 20%; + height: 100%; + position: relative; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; + flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex: 1 0; +} +#resizer { + position: absolute; + right: -5px; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; + z-index: 9999; +} +#main { + flex: 5 1; + -webkit-flex: 5 1; + -ms-flex: 5 1; + outline: none; + position: relative; + background: #fff; + padding: 1.2em; + padding-top: 0.2em; + box-sizing: border-box; +} + +@media (max-width: 920px) { + .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } + #resizer { display: none; } + #nav { + z-index: 9999; + background: #fff; + display: none; + position: absolute; + top: 40px; + right: 12px; + width: 500px; + max-width: 80%; + height: 80%; + overflow-y: scroll; + border: 1px solid #999; + border-collapse: collapse; + box-shadow: -7px 5px 25px #aaa; + border-radius: 2px; + } +} + +@media (min-width: 920px) { + body { height: 100%; overflow: hidden; } + #main { height: 100%; overflow: auto; } + #search { display: none; } +} + +#main img { max-width: 100%; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; + position: relative; +} +h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } +h2 small a { + display: block; + height: 20px; + border: 1px solid #aaa; + border-bottom: 0; + border-top-left-radius: 5px; + background: #f8f8f8; + position: relative; + padding: 2px 7px; +} +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } +.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { + color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link a, .docstring .object_link a { + font-family: monospace; font-size: 1.05em; + color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } +.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { + padding: 0px; background: inherit; color: inherit; border-radius: inherit; +} + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
    */ +#filecontents li > p, .docstring li > p { margin: 0px; } +#filecontents ul, .docstring ul { padding-left: 20px; } +/* style for
    */ +#filecontents dl, .docstring dl { border: 1px solid #ccc; } +#filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; } +#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; } +#filecontents dd > p, .docstring dd > p { margin: 0px; } + +.note { + color: #222; + margin: 20px 0; + padding: 10px; + border: 1px solid #eee; + border-radius: 3px; + display: block; +} +.docstring .note { + border-left-color: #ccc; + border-left-width: 5px; +} +.note.todo { background: #ffffc5; border-color: #ececaa; } +.note.returns_void { background: #efefef; } +.note.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.title.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.private { background: #ffffc5; border-color: #ececaa; } +.note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; } +.summary_signature + .note.title { margin-left: 7px; } +h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; } +.note.title { background: #efefef; } +.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; } +.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.private { background: #d5d5d5; border-color: #c5c5c5; } +.note.title.not_defined_here { background: transparent; border: none; font-style: italic; } +.discussion .note { margin-top: 6px; } +.discussion .note:first-child { margin-top: 0; } + +h3.inherited { + font-style: italic; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-weight: normal; + padding: 0; + margin: 0; + margin-top: 12px; + margin-bottom: 3px; + font-size: 13px; +} +p.inherited { + padding: 0; + margin: 0; + margin-left: 25px; +} + +.box_info dl { + margin: 0; + border: 0; + width: 100%; + font-size: 1em; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} +.box_info dl dt { + flex-shrink: 0; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + width: 100px; + text-align: right; + font-weight: bold; + border: 1px solid #aaa; + border-width: 1px 0px 0px 1px; + padding: 6px 0; + padding-right: 10px; +} +.box_info dl dd { + flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex: 1; + max-width: 420px; + padding: 6px 0; + padding-right: 20px; + border: 1px solid #aaa; + border-width: 1px 1px 0 0; + overflow: hidden; + position: relative; +} +.box_info dl:last-child > * { + border-bottom: 1px solid #aaa; +} +.box_info dl:nth-child(odd) > * { background: #eee; } +.box_info dl:nth-child(even) > * { background: #fff; } +.box_info dl > * { margin: 0; } + +ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; } +.index_inline_list { padding-left: 0; font-size: 1.1em; } + +.index_inline_list li { + list-style: none; + display: inline-block; + padding: 0 12px; + line-height: 30px; + margin-bottom: 5px; +} + +dl.constants { margin-left: 10px; } +dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; } +dl.constants.compact dt { display: inline-block; font-weight: normal } +dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; } +dl.constants .docstring .note:first-child { margin-top: 5px; } + +.summary_desc { + margin-left: 32px; + display: block; + font-family: sans-serif; + font-size: 1.1em; + margin-top: 8px; + line-height: 1.5145em; + margin-bottom: 0.8em; +} +.summary_desc tt { font-size: 0.9em; } +dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; } +dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; } +dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; } +dl.constants .discussion *:first-child { margin-top: 0; } +dl.constants .discussion *:last-child { margin-bottom: 0; } + +.method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; } +.method_details.first { border: 0; margin-top: 5px; } +.method_details.first h3.signature { margin-top: 1em; } +p.signature, h3.signature { + font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace; + padding: 6px 10px; margin-top: 1em; + background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px; +} +p.signature tt, +h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; } +p.signature .overload, +h3.signature .overload { display: block; } +p.signature .extras, +h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; } +p.signature .not_defined_here, +h3.signature .not_defined_here, +p.signature .aliases, +h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; } +p.signature .aliases .names, +h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; } + +.tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; } +.tags .tag_title tt { color: initial; padding: initial; background: initial; } +.tags ul { margin-top: 5px; padding-left: 30px; list-style: square; } +.tags ul li { margin-bottom: 3px; } +.tags ul .name { font-family: monospace; font-weight: bold; } +.tags ul .note { padding: 3px 6px; } +.tags { margin-bottom: 12px; } + +.tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; } +.tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; } +.tags .examples .inline p:before { content: "â–¸"; font-size: 1em; margin-right: 5px; } + +.tags .overload .overload_item { list-style: none; margin-bottom: 25px; } +.tags .overload .overload_item .signature { + padding: 2px 8px; + background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px; +} +.tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; } +.tags .overload .docstring { margin-top: 15px; } + +.defines { display: none; } + +#method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; } + +.showSource { font-size: 0.9em; } +.showSource a, .showSource a:visited { text-decoration: none; color: #666; } + +#content a, #content a:visited { text-decoration: none; color: #05a; } +#content a:hover { background: #ffffa5; } + +ul.summary { + list-style: none; + font-family: monospace; + font-size: 1em; + line-height: 1.5em; + padding-left: 0px; +} +ul.summary a, ul.summary a:visited { + text-decoration: none; font-size: 1.1em; +} +ul.summary li { margin-bottom: 5px; } +.summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; } +.summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; } +.summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; } +ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;} +ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; } +#content .summary_signature:hover a, +#content .summary_signature:hover a:visited { + background: transparent; + color: #049; +} + +p.inherited a { font-family: monospace; font-size: 0.9em; } +p.inherited { word-spacing: 5px; font-size: 1.2em; } + +p.children { font-size: 1.2em; } +p.children a { font-size: 0.9em; } +p.children strong { font-size: 0.8em; } +p.children strong.modules { padding-left: 5px; } + +ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; } +ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; } +ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAHtJREFUeNqMzrEJAkEURdGzuhgZbSoYWcAWoBVsB4JgZAGmphsZCZYzTQgWNCYrDN9RvMmHx+X916SUBFbo8CzD1idXrLErw1mQttgXtyrOcQ/Ny5p4Qh+2XqLYYazsPWNTiuMkRxa4vcV+evuNAUOLIx5+c2hyzv7hNQC67Q+/HHmlEwAAAABJRU5ErkJggg==) no-repeat top center; } +ul.fullTree li:first-child { padding-top: 0; background: transparent; } +ul.fullTree li:last-child { padding-bottom: 0; } +.showAll ul.fullTree { display: block; } +.showAll .inheritName { display: none; } + +#search { position: absolute; right: 12px; top: 0px; z-index: 9000; } +#search a { + display: block; float: left; + padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a; + border: 1px solid #d8d8e5; + border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + background: #F1F8FF; + box-shadow: -1px 1px 3px #ddd; +} +#search a:hover { background: #f5faff; color: #06b; fill: #06b; } +#search a.active { + background: #568; padding-bottom: 20px; color: #fff; fill: #fff; + border: 1px solid #457; + border-top-left-radius: 5px; border-top-right-radius: 5px; +} +#search a.inactive { color: #999; fill: #999; } +.inheritanceTree, .toggleDefines { + float: right; + border-left: 1px solid #aaa; + position: absolute; top: 0; right: 0; + height: 100%; + background: #f6f6f6; + padding: 5px; + min-width: 55px; + text-align: center; +} + +#menu { font-size: 1.3em; color: #bbb; } +#menu .title, #menu a { font-size: 0.7em; } +#menu .title a { font-size: 1em; } +#menu .title { color: #555; } +#menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; } +#menu a:hover { color: #05a; } + +#footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; } +#footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; } +#footer a:hover { color: #05a; } + +#listing ul.alpha { font-size: 1.1em; } +#listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; } +#listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; } +#listing ul.alpha ul { margin: 0; padding-left: 15px; } +#listing ul small { color: #666; font-size: 0.7em; } + +li.r1 { background: #f0f0f0; } +li.r2 { background: #fafafa; } + +#content ul.summary li.deprecated .summary_signature a, +#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; } + +#toc { + position: relative; + float: right; + overflow-x: auto; + right: -3px; + margin-left: 20px; + margin-bottom: 20px; + padding: 20px; padding-right: 30px; + max-width: 300px; + z-index: 5000; + background: #fefefe; + border: 1px solid #ddd; + box-shadow: -2px 2px 6px #bbb; +} +#toc .title { margin: 0; } +#toc ol { padding-left: 1.8em; } +#toc li { font-size: 1.1em; line-height: 1.7em; } +#toc > ol > li { font-size: 1.1em; font-weight: bold; } +#toc ol > li > ol { font-size: 0.9em; } +#toc ol ol > li > ol { padding-left: 2.3em; } +#toc ol + li { margin-top: 0.3em; } +#toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } +#toc.hidden:hover { background: #fafafa; } +#filecontents h1 + #toc.nofloat { margin-top: 0; } +@media (max-width: 560px) { + #toc { + margin-left: 0; + margin-top: 16px; + float: none; + max-width: none; + } +} + +/* syntax highlighting */ +.source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; } +#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; } +#filecontents pre.code, .docstring pre.code { display: block; } +.source_code .lines { padding-right: 12px; color: #555; text-align: right; } +#filecontents pre.code, .docstring pre.code, +.tags pre.example { + padding: 9px 14px; + margin-top: 4px; + border: 1px solid #e1e1e8; + background: #f7f7f9; + border-radius: 4px; + font-size: 1em; + overflow-x: auto; + line-height: 1.2em; +} +pre.code { color: #000; tab-size: 2; } +pre.code .info.file { color: #555; } +pre.code .val { color: #036A07; } +pre.code .tstring_content, +pre.code .heredoc_beg, pre.code .heredoc_end, +pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep, +pre.code .words_beg, pre.code .words_end, pre.code .words_sep, +pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep, +pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep, +pre.code .tstring, pre.code .dstring { color: #036A07; } +pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s, +pre.code .rubyid_to_sym, pre.code .rubyid_to_f, +pre.code .dot + pre.code .id, +pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; } +pre.code .comment { color: #0066FF; } +pre.code .const, pre.code .constant { color: #585CF6; } +pre.code .label, +pre.code .symbol { color: #C5060B; } +pre.code .kw, +pre.code .rubyid_require, +pre.code .rubyid_extend, +pre.code .rubyid_include { color: #0000FF; } +pre.code .ivar { color: #318495; } +pre.code .gvar, +pre.code .rubyid_backref, +pre.code .rubyid_nth_ref { color: #6D79DE; } +pre.code .regexp, .dregexp { color: #036A07; } +pre.code a { border-bottom: 1px dotted #bbf; } +/* inline code */ +*:not(pre) > code { + padding: 1px 3px 1px 3px; + border: 1px solid #E1E1E8; + background: #F7F7F9; + border-radius: 4px; +} + +/* Color fix for links */ +#content .summary_desc pre.code .id > .object_link a, /* identifier */ +#content .docstring pre.code .id > .object_link a { color: #0085FF; } +#content .summary_desc pre.code .const > .object_link a, /* constant */ +#content .docstring pre.code .const > .object_link a { color: #585CF6; } diff --git a/client/Ruby/docs/file.README.html b/client/Ruby/docs/file.README.html new file mode 100644 index 00000000..cba860a9 --- /dev/null +++ b/client/Ruby/docs/file.README.html @@ -0,0 +1,115 @@ + + + + + + + File: README + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
    + + +
    +

    Juno

    + +

    Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file lib/juno. To experiment with that code, run bin/console for an interactive prompt.

    + +

    TODO: Delete this and the text above, and describe your gem

    + +

    Installation

    + +

    Add this line to your application's Gemfile:

    + +
    gem 'juno'
    +
    + +

    And then execute:

    + +
    $ bundle
    +
    + +

    Or install it yourself as:

    + +
    $ gem install juno
    +
    + +

    Usage

    + +

    TODO: Write usage instructions here

    + +

    Development

    + +

    After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.

    + +

    To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

    + +

    Contributing

    + +

    Bug reports and pull requests are welcome on GitHub at github.com/[USERNAME]/juno. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

    + +

    License

    + +

    The gem is available as open source under the terms of the MIT License.

    + +

    Code of Conduct

    + +

    Everyone interacting in the Juno project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the of conduct[https://github.com/[USERNAME]/juno/blob/master/CODE_OF_CONDUCT.md].

    +
    + + + +
    + + \ No newline at end of file diff --git a/client/Ruby/docs/file_list.html b/client/Ruby/docs/file_list.html new file mode 100644 index 00000000..2b6df404 --- /dev/null +++ b/client/Ruby/docs/file_list.html @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + File List + + + +
    +
    +

    File List

    + + + +
    + + +
    + + diff --git a/client/Ruby/docs/frames.html b/client/Ruby/docs/frames.html new file mode 100644 index 00000000..4f918f57 --- /dev/null +++ b/client/Ruby/docs/frames.html @@ -0,0 +1,17 @@ + + + + + Documentation by YARD 0.9.34 + + + + diff --git a/client/Ruby/docs/index.html b/client/Ruby/docs/index.html new file mode 100644 index 00000000..fe4b31b4 --- /dev/null +++ b/client/Ruby/docs/index.html @@ -0,0 +1,115 @@ + + + + + + + File: README + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
    + + +
    +

    Juno

    + +

    Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file lib/juno. To experiment with that code, run bin/console for an interactive prompt.

    + +

    TODO: Delete this and the text above, and describe your gem

    + +

    Installation

    + +

    Add this line to your application's Gemfile:

    + +
    gem 'juno'
    +
    + +

    And then execute:

    + +
    $ bundle
    +
    + +

    Or install it yourself as:

    + +
    $ gem install juno
    +
    + +

    Usage

    + +

    TODO: Write usage instructions here

    + +

    Development

    + +

    After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.

    + +

    To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

    + +

    Contributing

    + +

    Bug reports and pull requests are welcome on GitHub at github.com/[USERNAME]/juno. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

    + +

    License

    + +

    The gem is available as open source under the terms of the MIT License.

    + +

    Code of Conduct

    + +

    Everyone interacting in the Juno project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the of conduct[https://github.com/[USERNAME]/juno/blob/master/CODE_OF_CONDUCT.md].

    +
    + + + +
    + + \ No newline at end of file diff --git a/client/Ruby/docs/js/app.js b/client/Ruby/docs/js/app.js new file mode 100644 index 00000000..8d067fe3 --- /dev/null +++ b/client/Ruby/docs/js/app.js @@ -0,0 +1,314 @@ +(function() { + +var localStorage = {}, sessionStorage = {}; +try { localStorage = window.localStorage; } catch (e) { } +try { sessionStorage = window.sessionStorage; } catch (e) { } + +function createSourceLinks() { + $('.method_details_list .source_code'). + before("[View source]"); + $('.toggleSource').toggle(function() { + $(this).parent().nextAll('.source_code').slideDown(100); + $(this).text("Hide source"); + }, + function() { + $(this).parent().nextAll('.source_code').slideUp(100); + $(this).text("View source"); + }); +} + +function createDefineLinks() { + var tHeight = 0; + $('.defines').after(" more..."); + $('.toggleDefines').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).prev().css('display', 'inline'); + $(this).parent().prev().height($(this).parent().height()); + $(this).text("(less)"); + }, + function() { + $(this).prev().hide(); + $(this).parent().prev().height(tHeight); + $(this).text("more..."); + }); +} + +function createFullTreeLinks() { + var tHeight = 0; + $('.inheritanceTree').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).parent().toggleClass('showAll'); + $(this).text("(hide)"); + $(this).parent().prev().height($(this).parent().height()); + }, + function() { + $(this).parent().toggleClass('showAll'); + $(this).parent().prev().height(tHeight); + $(this).text("show all"); + }); +} + +function searchFrameButtons() { + $('.full_list_link').click(function() { + toggleSearchFrame(this, $(this).attr('href')); + return false; + }); + window.addEventListener('message', function(e) { + if (e.data === 'navEscape') { + $('#nav').slideUp(100); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); + + $(window).resize(function() { + if ($('#search:visible').length === 0) { + $('#nav').removeAttr('style'); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); +} + +function toggleSearchFrame(id, link) { + var frame = $('#nav'); + $('#search a').removeClass('active').addClass('inactive'); + if (frame.attr('src') === link && frame.css('display') !== "none") { + frame.slideUp(100); + $('#search a').removeClass('active inactive'); + } + else { + $(id).addClass('active').removeClass('inactive'); + if (frame.attr('src') !== link) frame.attr('src', link); + frame.slideDown(100); + } +} + +function linkSummaries() { + $('.summary_signature').click(function() { + document.location = $(this).find('a').attr('href'); + }); +} + +function summaryToggle() { + $('.summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('ul.summary').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('ul.summary').first().toggle(); + } + else if (next.hasClass('summary')) { + var list = $('
      '); + list.html(next.html()); + list.find('.summary_desc, .note').remove(); + list.find('a').each(function() { + $(this).html($(this).find('strong').html()); + $(this).parent().html($(this)[0].outerHTML); + }); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function constantSummaryToggle() { + $('.constants_summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.constants_summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('dl.constants').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('dl.constants').first().toggle(); + } + else if (next.hasClass('constants')) { + var list = $('
      '); + list.html(next.html()); + list.find('dt').each(function() { + $(this).addClass('summary_signature'); + $(this).text( $(this).text().split('=')[0]); + if ($(this).has(".deprecated").length) { + $(this).addClass('deprecated'); + }; + }); + // Add the value of the constant as "Tooltip" to the summary object + list.find('pre.code').each(function() { + console.log($(this).parent()); + var dt_element = $(this).parent().prev(); + var tooltip = $(this).text(); + if (dt_element.hasClass("deprecated")) { + tooltip = 'Deprecated. ' + tooltip; + }; + dt_element.attr('title', tooltip); + }); + list.find('.docstring, .tags, dd').remove(); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.constants_summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function generateTOC() { + if ($('#filecontents').length === 0) return; + var _toc = $('
        '); + var show = false; + var toc = _toc; + var counter = 0; + var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; + var i; + var curli; + if ($('#filecontents h1').length > 1) tags.unshift('h1'); + for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } + var lastTag = parseInt(tags[0][1], 10); + $(tags.join(', ')).each(function() { + if ($(this).parents('.method_details .docstring').length != 0) return; + if (this.id == "filecontents") return; + show = true; + var thisTag = parseInt(this.tagName[1], 10); + if (this.id.length === 0) { + var proposedId = $(this).attr('toc-id'); + if (typeof(proposedId) != "undefined") this.id = proposedId; + else { + var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_'); + if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; } + this.id = proposedId; + } + } + if (thisTag > lastTag) { + for (i = 0; i < thisTag - lastTag; i++) { + if ( typeof(curli) == "undefined" ) { + curli = $('
      1. '); + toc.append(curli); + } + toc = $('
          '); + curli.append(toc); + curli = undefined; + } + } + if (thisTag < lastTag) { + for (i = 0; i < lastTag - thisTag; i++) { + toc = toc.parent(); + toc = toc.parent(); + } + } + var title = $(this).attr('toc-title'); + if (typeof(title) == "undefined") title = $(this).text(); + curli =$('
        1. ' + title + '
        2. '); + toc.append(curli); + lastTag = thisTag; + }); + if (!show) return; + html = ''; + $('#content').prepend(html); + $('#toc').append(_toc); + $('#toc .hide_toc').toggle(function() { + $('#toc .top').slideUp('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }, function() { + $('#toc .top').slideDown('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }); +} + +function navResizeFn(e) { + if (e.which !== 1) { + navResizeFnStop(); + return; + } + + sessionStorage.navWidth = e.pageX.toString(); + $('.nav_wrap').css('width', e.pageX); + $('.nav_wrap').css('-ms-flex', 'inherit'); +} + +function navResizeFnStop() { + $(window).unbind('mousemove', navResizeFn); + window.removeEventListener('message', navMessageFn, false); +} + +function navMessageFn(e) { + if (e.data.action === 'mousemove') navResizeFn(e.data.event); + if (e.data.action === 'mouseup') navResizeFnStop(); +} + +function navResizer() { + $('#resizer').mousedown(function(e) { + e.preventDefault(); + $(window).mousemove(navResizeFn); + window.addEventListener('message', navMessageFn, false); + }); + $(window).mouseup(navResizeFnStop); + + if (sessionStorage.navWidth) { + navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)}); + } +} + +function navExpander() { + var done = false, timer = setTimeout(postMessage, 500); + function postMessage() { + if (done) return; + clearTimeout(timer); + var opts = { action: 'expand', path: pathId }; + document.getElementById('nav').contentWindow.postMessage(opts, '*'); + done = true; + } + + window.addEventListener('message', function(event) { + if (event.data === 'navReady') postMessage(); + return false; + }, false); +} + +function mainFocus() { + var hash = window.location.hash; + if (hash !== '' && $(hash)[0]) { + $(hash)[0].scrollIntoView(); + } + + setTimeout(function() { $('#main').focus(); }, 10); +} + +function navigationChange() { + // This works around the broken anchor navigation with the YARD template. + window.onpopstate = function() { + var hash = window.location.hash; + if (hash !== '' && $(hash)[0]) { + $(hash)[0].scrollIntoView(); + } + }; +} + +$(document).ready(function() { + navResizer(); + navExpander(); + createSourceLinks(); + createDefineLinks(); + createFullTreeLinks(); + searchFrameButtons(); + linkSummaries(); + summaryToggle(); + constantSummaryToggle(); + generateTOC(); + mainFocus(); + navigationChange(); +}); + +})(); diff --git a/client/Ruby/docs/js/full_list.js b/client/Ruby/docs/js/full_list.js new file mode 100644 index 00000000..59069c5e --- /dev/null +++ b/client/Ruby/docs/js/full_list.js @@ -0,0 +1,216 @@ +(function() { + +var $clicked = $(null); +var searchTimeout = null; +var searchCache = []; +var caseSensitiveMatch = false; +var ignoreKeyCodeMin = 8; +var ignoreKeyCodeMax = 46; +var commandKey = 91; + +RegExp.escape = function(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); +} + +function escapeShortcut() { + $(document).keydown(function(evt) { + if (evt.which == 27) { + window.parent.postMessage('navEscape', '*'); + } + }); +} + +function navResizer() { + $(window).mousemove(function(e) { + window.parent.postMessage({ + action: 'mousemove', event: {pageX: e.pageX, which: e.which} + }, '*'); + }).mouseup(function(e) { + window.parent.postMessage({action: 'mouseup'}, '*'); + }); + window.parent.postMessage("navReady", "*"); +} + +function clearSearchTimeout() { + clearTimeout(searchTimeout); + searchTimeout = null; +} + +function enableLinks() { + // load the target page in the parent window + $('#full_list li').on('click', function(evt) { + $('#full_list li').removeClass('clicked'); + $clicked = $(this); + $clicked.addClass('clicked'); + evt.stopPropagation(); + + if (evt.target.tagName === 'A') return true; + + var elem = $clicked.find('> .item .object_link a')[0]; + var e = evt.originalEvent; + var newEvent = new MouseEvent(evt.originalEvent.type); + newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); + elem.dispatchEvent(newEvent); + evt.preventDefault(); + return false; + }); +} + +function enableToggles() { + // show/hide nested classes on toggle click + $('#full_list a.toggle').on('click', function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + $(this).parent().parent().toggleClass('collapsed'); + highlight(); + }); +} + +function populateSearchCache() { + $('#full_list li .item').each(function() { + var $node = $(this); + var $link = $node.find('.object_link a'); + if ($link.length > 0) { + searchCache.push({ + node: $node, + link: $link, + name: $link.text(), + fullName: $link.attr('title').split(' ')[0] + }); + } + }); +} + +function enableSearch() { + $('#search input').keyup(function(event) { + if (ignoredKeyPress(event)) return; + if (this.value === "") { + clearSearch(); + } else { + performSearch(this.value); + } + }); + + $('#full_list').after(""); +} + +function ignoredKeyPress(event) { + if ( + (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || + (event.keyCode == commandKey) + ) { + return true; + } else { + return false; + } +} + +function clearSearch() { + clearSearchTimeout(); + $('#full_list .found').removeClass('found').each(function() { + var $link = $(this).find('.object_link a'); + $link.text($link.text()); + }); + $('#full_list, #content').removeClass('insearch'); + $clicked.parents().removeClass('collapsed'); + highlight(); +} + +function performSearch(searchString) { + clearSearchTimeout(); + $('#full_list, #content').addClass('insearch'); + $('#noresults').text('').hide(); + partialSearch(searchString, 0); +} + +function partialSearch(searchString, offset) { + var lastRowClass = ''; + var i = null; + for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { + var item = searchCache[i]; + var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); + var matchString = buildMatchString(searchString); + var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); + if (searchName.match(matchRegexp) == null) { + item.node.removeClass('found'); + item.link.text(item.link.text()); + } + else { + item.node.addClass('found'); + item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); + lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; + item.link.html(item.name.replace(matchRegexp, "$&")); + } + } + if(i == searchCache.length) { + searchDone(); + } else { + searchTimeout = setTimeout(function() { + partialSearch(searchString, i); + }, 0); + } +} + +function searchDone() { + searchTimeout = null; + highlight(); + if ($('#full_list li:visible').size() === 0) { + $('#noresults').text('No results were found.').hide().fadeIn(); + } else { + $('#noresults').text('').hide(); + } + $('#content').removeClass('insearch'); +} + +function buildMatchString(searchString, event) { + caseSensitiveMatch = searchString.match(/[A-Z]/) != null; + var regexSearchString = RegExp.escape(searchString); + if (caseSensitiveMatch) { + regexSearchString += "|" + + $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). + join('.+?'); + } + return regexSearchString; +} + +function highlight() { + $('#full_list li:visible').each(function(n) { + $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); + }); +} + +/** + * Expands the tree to the target element and its immediate + * children. + */ +function expandTo(path) { + var $target = $(document.getElementById('object_' + path)); + $target.addClass('clicked'); + $target.removeClass('collapsed'); + $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); + if($target[0]) { + window.scrollTo(window.scrollX, $target.offset().top - 250); + highlight(); + } +} + +function windowEvents(event) { + var msg = event.data; + if (msg.action === "expand") { + expandTo(msg.path); + } + return false; +} + +window.addEventListener("message", windowEvents, false); + +$(document).ready(function() { + escapeShortcut(); + navResizer(); + enableLinks(); + enableToggles(); + populateSearchCache(); + enableSearch(); +}); + +})(); diff --git a/client/Ruby/docs/js/jquery.js b/client/Ruby/docs/js/jquery.js new file mode 100644 index 00000000..198b3ff0 --- /dev/null +++ b/client/Ruby/docs/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
    "+""+"
    ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
    t
    ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
    ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/client/Ruby/docs/method_list.html b/client/Ruby/docs/method_list.html new file mode 100644 index 00000000..4332e85c --- /dev/null +++ b/client/Ruby/docs/method_list.html @@ -0,0 +1,2075 @@ + + + + + + + + + + + + + + + + + + Method List + + + +
    +
    +

    Method List

    + + + +
    + + +
    + + diff --git a/client/Ruby/docs/top-level-namespace.html b/client/Ruby/docs/top-level-namespace.html new file mode 100644 index 00000000..469ccbb5 --- /dev/null +++ b/client/Ruby/docs/top-level-namespace.html @@ -0,0 +1,110 @@ + + + + + + + Top Level Namespace + + — Documentation by YARD 0.9.34 + + + + + + + + + + + + + + + + + + + +
    + + +

    Top Level Namespace + + + +

    +
    + + + + + + + + + + + +
    + +

    Defined Under Namespace

    +

    + + + Modules: Juno + + + + +

    + + + + + + + + + +
    + + + +
    + + \ No newline at end of file diff --git a/client/Ruby/juno.yml b/client/Ruby/juno.yml new file mode 100644 index 00000000..d2fdf125 --- /dev/null +++ b/client/Ruby/juno.yml @@ -0,0 +1,26 @@ +juno: + useSSL: true + default_record_lifetime_sec: 1800 + max_record_lifetime_sec: 259200 + max_record_namespace_length: 256 + max_key_size: 128 + application_name: TestApp + record_namespace: TestNamespace + usePayloadCompression: false + operation: + retry: true + response: + timeout_msec: 2000 + max_timeout_msec: 5000 + connection: + timeout_msec: 300 + recycle_duration_msec: 30000 + pool_size: 10 + reconnect_on_fail: false + byPassLTM: true + max_timeout_msec: 3000 + max_recycle_duration_msec: 50000 + max_pool_size: 20 + server: + host: "127.0.0.1" + port: 8080 diff --git a/client/Ruby/juno/.rspec b/client/Ruby/juno/.rspec new file mode 100644 index 00000000..c99d2e73 --- /dev/null +++ b/client/Ruby/juno/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/client/Ruby/juno/CODE_OF_CONDUCT.md b/client/Ruby/juno/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..7fed206e --- /dev/null +++ b/client/Ruby/juno/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at TODO: Write your email address. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/client/Ruby/juno/Gemfile b/client/Ruby/juno/Gemfile new file mode 100644 index 00000000..30277c73 --- /dev/null +++ b/client/Ruby/juno/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Gemfile + +source 'http://rubygems.org' + +git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } + +# Specify your gem's dependencies in juno.gemspec +gemspec diff --git a/client/Ruby/juno/Gemfile.lock b/client/Ruby/juno/Gemfile.lock new file mode 100644 index 00000000..9bf1e713 --- /dev/null +++ b/client/Ruby/juno/Gemfile.lock @@ -0,0 +1,95 @@ +PATH + remote: . + specs: + juno (1.0.0) + bindata (~> 2.4.15) + concurrent-ruby (~> 1.2.2) + configatron (~> 4.5.1) + eventmachine (~> 1.2.7) + json (~> 2.5.1) + logger (~> 1.2.7) + openssl (~> 2.2.0) + snappy (~> 0.3.0) + uri (~> 0.12.2) + uuidtools (~> 2.2.0) + yaml (~> 0.1.1) + +GEM + remote: http://rubygems.org/ + specs: + ast (2.4.2) + bindata (2.4.15) + concurrent-ruby (1.2.2) + configatron (4.5.1) + diff-lcs (1.5.0) + eventmachine (1.2.7) + ffi (1.15.5) + get_process_mem (0.2.7) + ffi (~> 1.0) + ipaddr (1.2.5) + json (2.5.1) + language_server-protocol (3.17.0.3) + logger (1.2.8.1) + openssl (2.2.3) + ipaddr + parallel (1.23.0) + parser (3.2.2.3) + ast (~> 2.4.1) + racc + racc (1.7.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.8.1) + rexml (3.2.6) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-html-formatter (0.0.1) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + rubocop (1.55.0) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.3) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + ruby-prof (1.6.3) + ruby-progressbar (1.13.0) + snappy (0.3.0) + unicode-display_width (2.4.2) + uri (0.12.2) + uuidtools (2.2.0) + yaml (0.1.1) + yard (0.9.34) + +PLATFORMS + arm64-darwin-21 + +DEPENDENCIES + bundler + get_process_mem + juno! + rake + rspec + rspec-html-formatter + rubocop + ruby-prof + yard + +BUNDLED WITH + 2.2.3 diff --git a/client/Ruby/juno/LICENSE.txt b/client/Ruby/juno/LICENSE.txt new file mode 100644 index 00000000..1c7e4b6b --- /dev/null +++ b/client/Ruby/juno/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 TODO: Write your name + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/client/Ruby/juno/Rakefile b/client/Ruby/juno/Rakefile new file mode 100644 index 00000000..bcab8af9 --- /dev/null +++ b/client/Ruby/juno/Rakefile @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'yard' + +task default: :spec + +RSpec::Core::RakeTask.new(:spec) do |t| + t.pattern = Dir.glob('spec/**/*_spec.rb') + t.rspec_opts = ['--format html', '--out juno_spec_results.html'] +end + +RuboCop::RakeTask.new(:lint) do |task| + task.patterns = ['lib/**/*.rb'] + task.options = ['--autocorrect', '--fail-level', 'error'] +end + +namespace :yard do + task :before_yard do + FileUtils.rm_rf('../docs') if Dir.exist?('../docs') + FileUtils.rm_rf('doc') if Dir.exist?('doc') + end + + task :after_yard do + FileUtils.mv('doc', '../docs') + FileUtils.rm_rf('.yardoc') + end + + YARD::Rake::YardocTask.new(:document) do |task| + task.files = ['lib/**/*.rb'] + task.before = -> { Rake::Task['yard:before_yard'].invoke } + task.after = -> { Rake::Task['yard:after_yard'].invoke } + end +end diff --git a/client/Ruby/juno/bin/console b/client/Ruby/juno/bin/console new file mode 100755 index 00000000..1224dcae --- /dev/null +++ b/client/Ruby/juno/bin/console @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'bundler/setup' +require 'juno' + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require 'irb' +IRB.start(__FILE__) diff --git a/client/Ruby/juno/bin/setup b/client/Ruby/juno/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/client/Ruby/juno/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/client/Ruby/juno/juno.gemspec b/client/Ruby/juno/juno.gemspec new file mode 100644 index 00000000..46425d76 --- /dev/null +++ b/client/Ruby/juno/juno.gemspec @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +lib = File.expand_path('lib', __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'juno/version' + +Gem::Specification.new do |spec| + spec.name = 'juno' + spec.version = Juno::VERSION + spec.authors = ['PayPal Inc'] + spec.email = ['paypal.com'] + + spec.summary = 'Ruby gem for Juno client' + spec.description = 'Ruby gem for Juno client' + spec.homepage = 'https://github.com/paypal/junodb' + spec.license = 'MIT' + + if spec.respond_to?(:metadata) + spec.metadata['allowed_push_host'] = 'https://github.com/paypal/junodb' + + spec.metadata['homepage_uri'] = spec.homepage + spec.metadata['source_code_uri'] = 'https://github.com/paypal/junodb' + spec.metadata['changelog_uri'] = 'https://github.com/paypal/junodb' + else + raise 'RubyGems 2.0 or newer is required to protect against ' \ + 'public gem pushes.' + end + + spec.files = Dir.chdir(File.expand_path(__dir__)) do + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + spec.bindir = 'exe' + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ['lib'] + + spec.add_development_dependency 'bundler' + spec.add_development_dependency 'get_process_mem' + spec.add_development_dependency 'rake' + spec.add_development_dependency 'rspec' + spec.add_development_dependency 'rspec-html-formatter' + spec.add_development_dependency 'rubocop' + spec.add_development_dependency 'ruby-prof' + spec.add_development_dependency 'yard' + + spec.add_runtime_dependency 'bindata', '~> 2.4.15' + spec.add_runtime_dependency 'concurrent-ruby', '~> 1.2.2' + spec.add_runtime_dependency 'configatron', '~> 4.5.1' + spec.add_runtime_dependency 'eventmachine', '~> 1.2.7' + spec.add_runtime_dependency 'json', '~> 2.5.1' + spec.add_runtime_dependency 'logger', '~> 1.2.7' + spec.add_runtime_dependency 'openssl', '~> 2.2.0' + spec.add_runtime_dependency 'snappy', '~> 0.3.0' + spec.add_runtime_dependency 'uri', '~> 0.12.2' + spec.add_runtime_dependency 'uuidtools', '~> 2.2.0' + spec.add_runtime_dependency 'yaml', '~> 0.1.1' +end diff --git a/client/Ruby/juno/lib/juno.rb b/client/Ruby/juno/lib/juno.rb new file mode 100644 index 00000000..22739d33 --- /dev/null +++ b/client/Ruby/juno/lib/juno.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'timeout' +require 'uuidtools' +require 'bindata' +require 'uri' +require 'json' +require 'yaml' +require 'logger' +require 'snappy' +require 'eventmachine' +require 'concurrent' +require 'configatron' + +require_relative 'juno/version' + +require_relative 'juno/Utils/utils' +require_relative 'juno/Utils/client_utils' + +require_relative 'juno/IO/constants' +require_relative 'juno/IO/JunoMessage' +require_relative 'juno/IO/MetadataComponentTemplate' +require_relative 'juno/IO/MetadataComponent' +require_relative 'juno/IO/PayloadComponent' +require_relative 'juno/IO/ProtocolHeader' +require_relative 'juno/IO/OperationMessage' + +require_relative 'juno/Net/base_processor' +require_relative 'juno/Net/ping_message' +require_relative 'juno/Net/request_queue' +require_relative 'juno/Net/client_handler' +require_relative 'juno/Net/io_processor' +require_relative 'juno/Net/worker_pool' + +require_relative 'juno/Config/config_reader' +require_relative 'juno/Config/config_provider' +require_relative 'juno/Config/properties' +require_relative 'juno/Config/default_properties' +require_relative 'juno/Config/config' + +require_relative 'juno/Client/operation_status' +require_relative 'juno/Client/operation_type' +require_relative 'juno/Client/juno_request' +require_relative 'juno/Client/record_context' +require_relative 'juno/Client/juno_response' +require_relative 'juno/Client/react_client' +require_relative 'juno/Client/cache_store' +require_relative 'juno/Client/sync_client' + +require_relative 'juno/server_status' +require_relative 'juno/logger' diff --git a/client/Ruby/juno/lib/juno/Client/cache_store.rb b/client/Ruby/juno/lib/juno/Client/cache_store.rb new file mode 100755 index 00000000..dadfbefb --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/cache_store.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Module for code exposed to the developer + module Client + # Cache store for ruby on rails + class CacheStore + def initialize + @react_client = Juno::Client::ReactClient.new + end + + def write(key, value, _options = {}) + future_obj = @react_client.set(key, value).wait + return false if future_obj.nil? + + raise future_obj.reason if future_obj.rejected? + + future_obj.value.status[:txnOk] + end + + def read(key, options = {}) + future_obj = @react_client.get(key).wait + read_response(future_obj, options[:version]) + end + + def self.supports_cache_versioning? + true + end + + def delete(key) + future_obj = @react_client.destroy(key).wait + return false if future_obj.nil? || future_obj.rejected? + + future_obj.value.status[:code] == Juno::Client::OperationStatus::SUCCESS[:code] + end + + def exist?(key) + !read(key).nil? + end + + private + + def read_response(future_obj, version) + return nil if future_obj.nil? || future_obj.rejected? + + return future_obj.value.value if version.nil? + + return future_obj.value.value if future_obj.record_context.version == version + + nil + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/juno_request.rb b/client/Ruby/juno/lib/juno/Client/juno_request.rb new file mode 100644 index 00000000..c2f2cf63 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/juno_request.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + module Client + # Request Object created from application request + class JunoRequest + class Type + CREATE = 1 + GET = 2 + UPDATE = 3 + SET = 4 + DESTROY = 5 + end + + attr_accessor :key, :version, :type, :value, :time_to_live_s, :creation_time + + # Constructor for JunoRequest + # @param key [String] key for the document (required) + # @param version [Integer] value for the document (required) + # @param version [Juno::JunoRequest::Type] value for the document (required) + # @param type [String] value for the document (optional, default: 1 byte string: 0.chr) + # @param type [Integer] Time to live for the document (optional, default: read from config file) + # @param type [Integer] Time to live for the document (optional, default: initialized to Time.now in JunoMessage) + def initialize(key:, version:, type:, value: nil, time_to_live_s: nil, creation_time: nil) + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @key = key + @version = version.to_i + @type = type + @value = value.to_s.empty? ? 0.chr : value.to_s + @time_to_live_s = time_to_live_s.to_i + @creation_time = creation_time + end + + def ==(other) + return false unless other.is_a?(JunoRequest) + + other.key == @key && + other.version == @version && + other.type == @type && + other.value == @value && + other.time_to_live_s == @time_to_live_s && + other.creation_time == @creation_time + end + + # Function to serialize JunoRequest + def to_s + "JunoRequest key:#{@key} version:#{@version} type:#{@type}, value: #{@value}, time_to_live: #{@time_to_live}, creation_time: #{@creation_time}" + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/juno_response.rb b/client/Ruby/juno/lib/juno/Client/juno_response.rb new file mode 100644 index 00000000..8c56732e --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/juno_response.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Juno + module Client + # Response sent to the application + class JunoResponse + attr_accessor :key, :status, :value, :record_context + + # @param key [String] (required) + # @param status [Juno::Client::OperationStatus] (required) + # @param value [String] (required) + # @param version [Integer] (required) + # @param creation_time [Integer] (required) + # @param time_to_live_s [Integer] (required) + def initialize(key:, value:, version:, time_to_live_s:, creation_time:, operation_status:) + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @key = key + @status = operation_status + @value = value + @record_context = Juno::Client::RecordContext.new(key: key, version: version, creation_time: creation_time, + time_to_live_s: time_to_live_s) + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/operation_status.rb b/client/Ruby/juno/lib/juno/Client/operation_status.rb new file mode 100644 index 00000000..538cf5ac --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/operation_status.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# Constant for Operation Status in JunoResponse +module Juno + module Client + class OperationStatus + SUCCESS = { code: 0, error_msg: 'No error', txnOk: true }.freeze + NO_KEY = { code: 1, error_msg: 'Key not found', txnOk: true }.freeze + BAD_PARAM = { code: 2, error_msg: 'Bad parameter', txnOk: false }.freeze + UNIQUE_KEY_VIOLATION = { code: 3, error_msg: 'Duplicate key', txnOk: true }.freeze + RECORD_LOCKED = { code: 4, error_msg: 'Record Locked', txnOk: true }.freeze + ILLEGAL_ARGUMENT = { code: 5, error_msg: 'Illegal argument', txnOk: false }.freeze + CONDITION_VIOLATION = { code: 6, error_msg: 'Condition in the request violated', txnOk: true }.freeze + INTERNAL_ERROR = { code: 7, error_msg: 'Internal error', txnOk: false }.freeze + QUEUE_FULL = { code: 8, error_msg: 'Outbound client queue full', txnOk: false }.freeze + NO_STORAGE = { code: 9, error_msg: 'No storage server running', txnOk: false }.freeze + TTL_EXTEND_FAILURE = { code: 10, error_msg: 'Failure to extend TTL on get', txnOk: true }.freeze + RESPONSE_TIMEOUT = { code: 11, error_msg: 'Response Timed out', txnOk: false }.freeze + CONNECTION_ERROR = { code: 12, error_msg: 'Connection Error', txnOk: false }.freeze + UNKNOWN_ERROR = { code: 13, error_msg: 'Unknown Error', txnOk: false }.freeze + + @@status_code_map = nil + + def self.initialize_map + @@status_code_map = {} + + constants.each do |const| + const_obj = const_get(const) + @@status_code_map[const_obj[:code]] = const_obj + end + end + + def self.get(status_code) + initialize_map if @@status_code_map.nil? + return @@status_code_map[status_code] if @@status_code_map.key?(status_code) + + INTERNAL_ERROR + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/operation_type.rb b/client/Ruby/juno/lib/juno/Client/operation_type.rb new file mode 100644 index 00000000..3f14f860 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/operation_type.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + module Client + # Constant for JunoRequest operation type + class OperationType + Nop = { + code: 0, + str: 'NOP' + }.freeze + Create = { + code: 1, + str: 'CREATE' + }.freeze + Get = { + code: 2, + str: 'GET' + }.freeze + Update = { + code: 3, + str: 'UPDATE' + }.freeze + Set = { + code: 4, + str: 'SET' + }.freeze + CompareAndSet = { + code: 5, + str: 'COMPAREANDSET' + }.freeze + Destroy = { + code: 6, + str: 'DESTROY' + }.freeze + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/react_client.rb b/client/Ruby/juno/lib/juno/Client/react_client.rb new file mode 100644 index 00000000..b7e1a0bc --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/react_client.rb @@ -0,0 +1,233 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Module for code exposed to the developer + module Client + # Async Client for Juno + class ReactClient + # @ Global Opaque generator. Uses ConcurrentFixnum for thread safety + @@OPAQUE_GENERATOR = Concurrent::AtomicFixnum.new(-1) + # @ Variable to count failed requests + @@fail_count = Concurrent::AtomicFixnum.new(0) + # @ Variable to count responses received + @@received = Concurrent::AtomicFixnum.new(0) + + # Constants for operation retry + MAX_OPERATION_RETRY = 1 + MAX_RETRY_INTERVAL = 15 # msec + MIN_RETRY_INTERVAL = 10 # msec + + def self.op_count + @@OPAQUE_GENERATOR.value + end + + def self.failed_count + @@fail_count.value + end + + def self.recv + @@received.value + end + + def initialize + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @request_queue = Juno::Net::RequestQueue.instance + @executor = Concurrent::ThreadPoolExecutor.new(min_threads: 4, max_threads: 16, max_queue: 10_000) + @count = 0 + end + + def stop + @LOGGER.info(@PROG_NAME) { 'stop initiated by client' } + @request_queue.stop + @executor.shutdown + @executor.wait_for_termination + @executor.kill + end + + # Function to create new key value pair + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Boolean] True if operation submited successfully, else false + # @see #process_single + # @see Juno::DefaultProperties::DEFAULT_LIFETIME_S + def create(key, value, ttl: nil) + juno_request = Juno::Client::JunoRequest.new(key: key, + value: value, + version: 0, + type: Juno::Client::JunoRequest::Type::CREATE, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + + # Function to set value for given key + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Boolean] True if operation submited successfully, else false + # @see #process_single + # @see Juno::DefaultProperties::DEFAULT_LIFETIME_S + def set(key, value, ttl: nil) + juno_request = Juno::Client::JunoRequest.new(key: key, + value: value, + version: 0, + type: Juno::Client::JunoRequest::Type::SET, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + # @!method write + # @see #create + alias write set + + def compare_and_set(record_context, value, ttl) + unless record_context.is_a?(Juno::Client::RecordContext) + raise ArgumentError, 'recird context should be of type Juno::Client::RecordContext' + end + raise ArgumentError, 'Version cannot be less than 1' if record_context.version.to_i < 1 + + juno_request = Juno::Client::JunoRequest.new(key: record_context.key.to_s, + value: value, + version: record_context.version.to_i, + type: Juno::Client::JunoRequest::Type::UPDATE, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + + # Function to get existing key value pair + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Juno::Client::JunoResponse] + # @see Juno::Client#process_single + # @see Juno::DefaultProperties::DEFAULT_LIFETIME_S + def get(key, ttl: nil) + juno_request = Juno::Client::JunoRequest.new(key: key, + value: '', + version: 0, + type: Juno::Client::JunoRequest::Type::GET, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + # @!method read + # @see #get + alias read get + + def update(key, value, ttl: nil) + juno_request = Juno::Client::JunoRequest.new(key: key, + value: value, + version: 0, + type: Juno::Client::JunoRequest::Type::UPDATE, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + + def destroy(key, ttl: nil) + juno_request = Juno::Client::JunoRequest.new(key: key, + value: '', + version: 0, + type: Juno::Client::JunoRequest::Type::DESTROY, + time_to_live_s: ttl, + creation_time: Time.now.to_i) + process_single(juno_request) + end + # @!method delete + # @see #destroy + alias delete destroy + + def exist?(key); end + + private + + # Function to process a request. Set operation retry true in config file + # @param ttl [Juno::Client::JunoRequest] + # @return [Boolean] True if operation submited successfully, else false + # @see Juno::ClientUtils#validate + # @see Juno::DefaultProperties::DEFAULT_LIFETIME_S + # @see Juno::Net::RequestQueue#opaque_resp_queue_map + def process_single(juno_request) + # rubocop:disable Style/SignalException + # Concurrent::Future object to execute asynchronously + Concurrent::Future.execute(executor: @executor) do + begin + begin + juno_message = Juno::ClientUtils.validate!(juno_request) + rescue ArgumentError => e + fail(e.message) + end + operation_retry = Juno.juno_config.operation_retry + juno_resp = nil + opaque = nil + opaque_resp_queue_map = @request_queue.opaque_resp_queue_map + (MAX_OPERATION_RETRY + 1).times do + opaque = @@OPAQUE_GENERATOR.increment + operation_message = Juno::ClientUtils.create_operation_message(juno_message, opaque) + + resp_queue = SizedQueue.new(1) + opaque_resp_queue_map[opaque] = resp_queue + + # map to compute response times for requests + msg_buffer = StringIO.new + operation_message.write(msg_buffer) + + fail('Queue full') unless @request_queue.push(msg_buffer.string, + operation_message&.metadata_component&.request_uuid.to_s) + + resp = nil + begin + Timeout.timeout(Juno.juno_config.response_timeout.to_f / 1000) do + resp = resp_queue.pop + end + rescue Timeout::Error + resp = nil + end + + if resp.nil? + fail('Request Timeout') unless operation_retry + + @LOGGER.debug(@PROG_NAME) { "Retrying #{opaque} " } + operation_retry = false + # Backoff time for request retry + sec = rand(MAX_RETRY_INTERVAL - MIN_RETRY_INTERVAL) + MIN_RETRY_INTERVAL + @LOGGER.debug(@PROG_NAME) { "Backoff time #{sec.to_f / 1000}ms " } + sleep(sec.to_f / 1000) + next + end + juno_resp_msg = Juno::ClientUtils.decode_operation_message(resp) + fail('Could not fetch valid response') if juno_resp_msg.nil? + + juno_resp = Juno::Client::JunoResponse.new(key: juno_resp_msg.key, value: juno_resp_msg.value, + version: juno_resp_msg.version, time_to_live_s: juno_resp_msg.time_to_live_s, + creation_time: juno_resp_msg.creation_time, + operation_status: juno_resp_msg.server_status[:client_operation_status]) + + fail(juno_resp.status[:error_msg]) unless [Juno::Client::OperationStatus::SUCCESS[:code], Juno::Client::OperationStatus::CONDITION_VIOLATION[:code], + Juno::Client::OperationStatus::NO_KEY[:code], Juno::Client::OperationStatus::RECORD_LOCKED[:code], + Juno::Client::OperationStatus::UNIQUE_KEY_VIOLATION[:code], Juno::Client::OperationStatus::TTL_EXTEND_FAILURE[:code]].include?(juno_resp.status[:code]) + + break + end + rescue StandardError => e + puts e.backtrace + fail(e) + ensure + opaque_resp_queue_map.delete(opaque) + @@fail_count.increment if juno_resp.nil? + @@received.increment unless juno_resp.nil? + # rubocop:enable Style/SignalException + end + juno_resp + end + rescue Concurrent::RejectedExecutionError + @LOGGER.error(@PROG_NAME) { 'Too many requests Concurrent::Future' } + nil + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/record_context.rb b/client/Ruby/juno/lib/juno/Client/record_context.rb new file mode 100644 index 00000000..1f2c50a6 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/record_context.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Juno + module Client + class RecordContext + attr_reader :key, :version, :creation_time, :time_to_live_s + + # @param key [String] (required) + # @param version [Integer] (required) + # @param creation_time [Integer] (required) + # @param time_to_live_s [Integer] (required) + def initialize(key:, version:, creation_time:, time_to_live_s:) + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @key = key + @version = version + @creation_time = creation_time + @time_to_live_s = time_to_live_s + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Client/sync_client.rb b/client/Ruby/juno/lib/juno/Client/sync_client.rb new file mode 100644 index 00000000..f7afc7cd --- /dev/null +++ b/client/Ruby/juno/lib/juno/Client/sync_client.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Module for code exposed to the developer + module Client + # Async Client for Juno + class SyncClient + def initialize + @react_client = Juno::Client::ReactClient.new + end + + # Function to create new key value pair + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Juno::Client::JunoResponse] + def create(key, value, ttl: nil) + juno_resp = @react_client.create(key, value, ttl: ttl).wait + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + + # Function to set value for given key + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Juno::Client::JunoResponse] + def set(key, value, ttl: nil) + juno_resp = @react_client.set(key.to_s, value.to_s, ttl: ttl).wait + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + + # Function to get existing key value pair + # @param key [String] key for the document (required) + # @param value [String] value for the document (required) + # @param ttl [Integer] Time to live for the document (optional, default: read from config file) + # @return [Juno::Client::JunoResponse] + def get(key, ttl: nil) + juno_resp = @react_client.get(key.to_s, ttl: ttl).wait + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + + def update(key, value, ttl: nil) + juno_resp = @react_client.update(key.to_s, value.to_s, ttl: ttl).wait + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + + def compare_and_set(record_context, value, ttl: nil) + juno_resp = nil + begin + juno_resp = @react_client.compare_and_set(record_context, value, ttl) + rescue ArgumentError => e + raise e.message + end + + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + + def destroy(key, ttl: nil) + juno_resp = @react_client.destroy(key.to_s, ttl: ttl).wait + return nil if juno_resp.nil? + + raise juno_resp.reason if juno_resp.rejected? + + juno_resp.value # JunoResponse + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Config/config.rb b/client/Ruby/juno/lib/juno/Config/config.rb new file mode 100644 index 00000000..d0254cb5 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Config/config.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Juno.configure do |config| + # config.record_namespace = "kk" + # config.host = '10.138.38.83' + # config.port = 5080 + # config.app_name = "TestApp" + # config.file_path = "" + # config.url = "" + # end + class Config + attr_reader :response_timeout, :connection_timeout, :connection_pool_size, :connection_lifetime, :default_lifetime, + :max_response_timeout, :max_connection_timeout, :max_connection_pool_size, :max_connection_lifetime, :max_lifetime, :max_key_size, :max_value_size, :max_namespace_length, + :host, :port, :app_name, :record_namespace, + :use_ssl, :use_payload_compression, :operation_retry, :bypass_ltm, :reconnect_on_fail, :config_prefix, + :log_file, :ssl_cert_file, :ssl_key_file + + REQUIRED_PROPERTIES = %i[host port app_name record_namespace log_file].freeze + + def initialize(config_provider, log_file:, ssl_cert_file: nil, ssl_key_file: nil) + @PROG_NAME = self.class.name + @log_file = log_file + @ssl_cert_file = ssl_cert_file + @ssl_key_file = ssl_key_file + @config = config_provider + read_all + validate! + end + + # Function to map all properties read from config file to variables + def read_all + @response_timeout = @config.get_property(Juno::Properties::RESPONSE_TIMEOUT, + Juno::DefaultProperties::RESPONSE_TIMEOUT_MS) + @connection_timeout = @config.get_property(Juno::Properties::CONNECTION_TIMEOUT, + Juno::DefaultProperties::CONNECTION_TIMEOUT_MS) + @connection_pool_size = @config.get_property(Juno::Properties::CONNECTION_POOLSIZE, + Juno::DefaultProperties::CONNECTION_POOLSIZE) + @connection_lifetime = @config.get_property(Juno::Properties::CONNECTION_LIFETIME, + Juno::DefaultProperties::CONNECTION_LIFETIME_MS) + @default_lifetime = @config.get_property(Juno::Properties::DEFAULT_LIFETIME, + Juno::DefaultProperties::DEFAULT_LIFETIME_S) + @max_response_timeout = @config.get_property(Juno::Properties::MAX_RESPONSE_TIMEOUT, + Juno::DefaultProperties::MAX_RESPONSE_TIMEOUT_MS) + @max_connection_timeout = @config.get_property(Juno::Properties::MAX_CONNECTION_TIMEOUT, + Juno::DefaultProperties::MAX_CONNECTION_TIMEOUT_MS) + @max_connection_pool_size = @config.get_property(Juno::Properties::MAX_CONNECTION_POOL_SIZE, + Juno::DefaultProperties::MAX_CONNECTION_POOL_SIZE) + @max_connection_lifetime = @config.get_property(Juno::Properties::MAX_CONNECTION_LIFETIME, + Juno::DefaultProperties::MAX_CONNECTION_LIFETIME_MS) + @max_lifetime = @config.get_property(Juno::Properties::MAX_LIFETIME, Juno::DefaultProperties::MAX_LIFETIME_S) + @max_key_size = @config.get_property(Juno::Properties::MAX_KEY_SIZE, Juno::DefaultProperties::MAX_KEY_SIZE_B) + @max_value_size = @config.get_property(Juno::Properties::MAX_VALUE_SIZE, + Juno::DefaultProperties::MAX_VALUE_SIZE_B) + @max_namespace_length = @config.get_property(Juno::Properties::MAX_NAMESPACE_LENGTH, + Juno::DefaultProperties::MAX_NAMESPACE_LENGTH) + @host = @config.get_property(Juno::Properties::HOST, Juno::DefaultProperties::HOST) + @port = @config.get_property(Juno::Properties::PORT, Juno::DefaultProperties::PORT) + @app_name = @config.get_property(Juno::Properties::APP_NAME, Juno::DefaultProperties::APP_NAME) + @record_namespace = @config.get_property(Juno::Properties::RECORD_NAMESPACE, + Juno::DefaultProperties::RECORD_NAMESPACE) + @use_ssl = @config.get_property(Juno::Properties::USE_SSL, Juno::DefaultProperties::USE_SSL) + @use_payload_compression = @config.get_property(Juno::Properties::USE_PAYLOAD_COMPRESSION, + Juno::DefaultProperties::USE_PAYLOAD_COMPRESSION) + @operation_retry = @config.get_property(Juno::Properties::ENABLE_RETRY, Juno::DefaultProperties::OPERATION_RETRY) + @bypass_ltm = @config.get_property(Juno::Properties::BYPASS_LTM, Juno::DefaultProperties::BYPASS_LTM) + @reconnect_on_fail = @config.get_property(Juno::Properties::RECONNECT_ON_FAIL, + Juno::DefaultProperties::RECONNECT_ON_FAIL) + @config_prefix = @config.get_property(Juno::Properties::CONFIG_PREFIX, Juno::DefaultProperties::CONFIG_PREFIX) + nil + end + + def validate! + missing_properties = [] + REQUIRED_PROPERTIES.each do |property| + missing_properties.push(property) if send(property).nil? + end + + if @use_ssl + %i[ssl_cert_file ssl_key_file].each do |property| + missing_properties.push(property) if send(property).nil? + end + end + + if missing_properties.length.positive? + raise "Please provide a value for the required property(s) #{missing_properties.join(', ')}." + end + + if @use_ssl + raise 'SSL Certificate file not found' unless File.exist?(@ssl_cert_file) + raise 'SSL Key file not found' unless File.exist?(@ssl_key_file) + end + + nil + end + + class Source + YAML_FILE = 0 + JSON_FILE = 1 + URL = 2 + end + end + + def self.configure + if @juno_config.nil? + config_reader = Juno::ConfigReader.new + yield config_reader + if !config_reader.file_path.nil? + @juno_config = Config.new(ConfigProvider.new(config_reader.file_path, config_reader.source_format, nil), + log_file: config_reader.log_file, ssl_cert_file: config_reader.ssl_cert_file, + ssl_key_file: config_reader.ssl_key_file) + @LOGGER = Juno::Logger.instance + elsif !config_reader.url.nil? # URL should URI Object + # @juno_config = Config.new(ConfigProvider.new(@juno_config.file_path, @juno_config.source_format, nil)) + else + raise 'No file or url provided' + end + else + Juno::Logger.instance.warn('Juno client cannot be reconfigured') + end + end + + def self.juno_config + raise 'Please configure the properties using Juno.configure' if @juno_config.nil? + + @juno_config + end +end diff --git a/client/Ruby/juno/lib/juno/Config/config_provider.rb b/client/Ruby/juno/lib/juno/Config/config_provider.rb new file mode 100644 index 00000000..3f5d9379 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Config/config_provider.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Class to read config from file or url + class ConfigProvider + # Constructor + # @param source_uri [URI] Ruby URI Object for file or URL (required) + # @param source_format [String] source_format required only for url. Inferred from file extension when using file (optional) + # @return Propert value. Return default_value if property not found + # @see Juno::Properties + def initialize(source_uri, source_format = nil, _http_handler = nil) + begin + source_scheme = source_uri&.send(:scheme) + rescue StandardError => e + raise "Invalid source_uri object.\n #{e.message}" + end + if source_scheme == 'file' + read_from_file(source_uri) + elsif source_scheme =~ /^http(s)?$/ + read_from_url(source_uri, source_format, http_handler) + else + raise 'Only local file and URL supported' + end + end + + # Function to intialize configatron object from config file/URL + # @param source_uri [URI] Ruby URI Object for file or URL (required) + # @return [nil] + def read_from_file(source_uri) + raise 'Config file not found' unless File.exist?(source_uri.path) + + hsh = if ['.yml', '.yaml'].include?(File.extname(source_uri.path)) + YAML.load_file(source_uri.path) + elsif ['.json'].inlcude?(File.extname(source_uri.path)) + json_text = File.read(source_uri.path) + JSON.parse(json_text) + else + raise 'Unknown file format' + end + configatron.configure_from_hash(hsh) + nil + end + + def read_from_url(source_uri, source_format, http_handler); end + + # Function to read propertied in the heirarchy define in Juno::Properties + # @param property_key [String] String key (required) + # @param default_value (optional) default value if property not found + # @return Propert value. Returns default_value if property not found + # @see Juno::Properties + def get_property(property_key, default_value = nil) + return default_value if property_key.to_s.empty? + + value = configatron.to_h + property_key.to_s.split('.').each do |k| + return default_value unless value.is_a?(Hash) && value.key?(k.to_sym) + + value = value[k.to_sym] + # puts "#{k} --- #{value}" + end + + value.nil? || value.is_a?(Hash) ? default_value : value + end + end +end diff --git a/client/Ruby/juno/lib/juno/Config/config_reader.rb b/client/Ruby/juno/lib/juno/Config/config_reader.rb new file mode 100644 index 00000000..4f8d3e68 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Config/config_reader.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Properties Reader - Properties to be read from the developer using Juno.configure + # Either file_path or url is required + # log device can be a filename or IO Object + class ConfigReader + attr_accessor :file_path, :url, :source_format, :http_handler, :log_level, :log_device, + :max_log_file_bytes, :log_rotation, :log_file, :ssl_cert_file, :ssl_key_file + + def initialize + # default values + @log_level = ::Logger::Severity::INFO + @max_log_file_bytes = 1_048_576 # default for inbuilt logger class + @log_device = $stdout + @log_rotation = 'daily' # daily, weekly, monthly + end + end +end diff --git a/client/Ruby/juno/lib/juno/Config/default_properties.rb b/client/Ruby/juno/lib/juno/Config/default_properties.rb new file mode 100644 index 00000000..fee42326 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Config/default_properties.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Module containing constant default values for Properties + class DefaultProperties + RESPONSE_TIMEOUT_MS = 200 + CONNECTION_TIMEOUT_MS = 200 + CONNECTION_POOLSIZE = 1 + CONNECTION_LIFETIME_MS = 30_000 + DEFAULT_LIFETIME_S = 259_200 + + # Max for all above property + MAX_RESPONSE_TIMEOUT_MS = 5000 + MAX_CONNECTION_LIFETIME_MS = 30_000 + MAX_CONNECTION_TIMEOUT_MS = 5000 + MAX_KEY_SIZE_B = 128 + MAX_VALUE_SIZE_B = 204_800 + MAX_NAMESPACE_LENGTH = 64 + MAX_CONNECTION_POOL_SIZE = 3 + MAX_LIFETIME_S = 259_200 + + # Required Properties + HOST = '' + PORT = 0 + APP_NAME = '' + RECORD_NAMESPACE = '' + + # optional Properties + CONFIG_PREFIX = '' + USE_SSL = true + RECONNECT_ON_FAIL = false + USE_PAYLOAD_COMPRESSION = false + OPERATION_RETRY = false + BYPASS_LTM = true + end +end diff --git a/client/Ruby/juno/lib/juno/Config/properties.rb b/client/Ruby/juno/lib/juno/Config/properties.rb new file mode 100644 index 00000000..488d12ac --- /dev/null +++ b/client/Ruby/juno/lib/juno/Config/properties.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Module for properties key (config file) + class Properties + RESPONSE_TIMEOUT = 'juno.response.timeout_msec' + CONNECTION_TIMEOUT = 'juno.connection.timeout_msec' + DEFAULT_LIFETIME = 'juno.default_record_lifetime_sec' + CONNECTION_LIFETIME = 'juno.connection.recycle_duration_msec' + CONNECTION_POOLSIZE = 'juno.connection.pool_size' + RECONNECT_ON_FAIL = 'juno.connection.reconnect_on_fail' + HOST = 'juno.server.host' + PORT = 'juno.server.port' + APP_NAME = 'juno.application_name' + RECORD_NAMESPACE = 'juno.record_namespace' + USE_SSL = 'juno.useSSL' + USE_PAYLOAD_COMPRESSION = 'juno.usePayloadCompression' + ENABLE_RETRY = 'juno.operation.retry' + BYPASS_LTM = 'juno.connection.byPassLTM' + CONFIG_PREFIX = 'prefix' + + # Max for each property + MAX_LIFETIME = 'juno.max_record_lifetime_sec' + MAX_KEY_SIZE = 'juno.max_key_size' + MAX_VALUE_SIZE = 'juno.max_value_size' + MAX_RESPONSE_TIMEOUT = 'juno.response.max_timeout_msec' + MAX_CONNECTION_TIMEOUT = 'juno.connection.max_timeout_msec' + MAX_CONNECTION_LIFETIME = 'juno.connection.max_recycle_duration_msec' + MAX_CONNECTION_POOL_SIZE = 'juno.connection.max_pool_size' + MAX_NAMESPACE_LENGTH = 'juno.max_record_namespace_length' + end +end diff --git a/client/Ruby/juno/lib/juno/IO/JunoMessage.rb b/client/Ruby/juno/lib/juno/IO/JunoMessage.rb new file mode 100644 index 00000000..7678fcf0 --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/JunoMessage.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Juno + module IO + # JunoMessage containing all configuration required to create an operation message + class JunoMessage + attr_accessor :operation_type, :server_status, + :namespace, :key, :value, :is_compressed, :compression_type, + :time_to_live_s, :version, :creation_time, :expiration_time, :request_uuid, + :ip, :app_name, :port, :last_modification, :originator_request_id, :correlation_id, + :request_handling_time, :request_start_time, :message_size, :compression_achieved, :expiry + + def initialize + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @operation_type = Juno::IO::JunoMessage::OperationType::NOP + @server_status = Juno::ServerStatus::SUCCESS + @compression_type = Juno::IO::CompressionType::None + @is_compressed = false + @compression_achieved = 0 + @message_size = 0 + @value = '' + end + + class OperationType + NOP = 0 + CREATE = 1 + GET = 2 + UPDATE = 3 + SET = 4 + DESTROY = 5 + + @@status_code_map = nil + + def self.initialize_map + @@status_code_map = {} + + constants.each do |const| + const_obj = const_get(const) + @@status_code_map[const_obj.to_i] = const_obj + end + end + + def self.get(status_code) + initialize_map if @@status_code_map.nil? + return @@status_code_map[status_code.to_i] if @@status_code_map.key?(status_code) + + INTERNAL_ERROR + end + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/MetadataComponent.rb b/client/Ruby/juno/lib/juno/IO/MetadataComponent.rb new file mode 100644 index 00000000..9b8c3c9a --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/MetadataComponent.rb @@ -0,0 +1,354 @@ +# frozen_string_literal: true + +module Juno + module IO + # + # ** MetaData Component ** + # A variable length header followed by a set of meta data fields + # Tag/ID: 0x02 + # * Header * + # + # | 0| 1| 2| 3| 4| 5| 6| 7| + # 0 | size | 4 bytes + # ----+-----------------------+--------- + # 4 | Tag/ID (0x02) | 1 byte + # ----+-----------------------+--------- + # 5 | Number of fields | 1 byte + # ----+--------------+--------+--------- + # 6 | Field tag |SizeType| 1 byte + # ----+--------------+--------+--------- + # | ... | + # ----+-----------------------+--------- + # | padding to 4 | + # ----+-----------------------+--------- + # (Don't think we need a header size. ) + # + # SizeType: + # 0 variable length field, for that case, + # the first 1 byte of the field MUST be + # the size of the field(padding to 4 byte). + # The max is 255. + # n Fixed length: 2 ^ (n+1) bytes + # + # + # + # * Body * + # ----+-----------------------+--------- + # | Field data | defined by Field tag + # ----+-----------------------+--------- + # | ... | + # ----+-----------------------+--------- + # | padding to 8 | + # ----+-----------------------+--------- + # + # * Predefined Field Types * + # + # TimeToLive Field + # Tag : 0x01 + # SizeType : 0x01 + # Version Field + # Tag : 0x02 + # SizeType : 0x01 + # Creation Time Field + # Tag : 0x03 + # SizeType : 0x01 + # Expiration Time Field + # Tag : 0x04 + # SizeType : 0x01 + # RequestID/UUID Field + # Tag : 0x05 + # SizeType : 0x03 + # Source Info Field + # Tag : 0x06 + # SizeType : 0 + # Last Modification time (nano second) + # Tag : 0x07 + # SizeType : 0x02 + # Originator RequestID Field + # Tag : 0x08 + # SizeType : 0x03 + # Correlation ID field + # Tag : 0x09 + # SizeType : 0x0 + # Request Handling Time Field + # Tag : 0x0a + # SizeType : 0x01 + # + # Tag: 0x06 + # + # | 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| + # | 0| 1| 2| 3| + # +-----------+-----------+--------------------+--+-----------------------+-----------------------+ + # | size (include padding)| app name length | T| Port | + # +-----------------------+--------------------+--+-----------------------------------------------+ + # | IPv4 address if T is 0 or IPv6 address if T is 1 | + # +-----------------------------------------------------------------------------------------------+ + # | application name, padding to 4-bytes aligned | + # +-----------------------------------------------------------------------------------------------+ + + # Wrapper class for MetadataComponentTemplate + class MetadataComponent + attr_reader :metadata_field_list, :time_to_live, :version, :creation_time, :expiration_time, :request_uuid, + :ip, :app_name, :port, :last_modification, :originator_request_id, :correlation_id, :request_handling_time + + def initialize + @PROG_NAME = self.class.name + # @LOGGER = Juno::Logger.instance + # @metadata_field_list [Array] + @metadata_field_list = [] + end + + # @param ttl [Integer] - Record Time to live + def set_time_to_live(ttl) + ttl = ttl.to_i + raise ArgumentError, 'TTL should be > 0' unless ttl.positive? + + @time_to_live = ttl + ttl = [ttl].pack(OffsetWidth.UINT32) + add_field(MetadataField.new(0x01, 0x01, ttl)) + end + + # @param version [Integer] - Record version + def set_version(data) + @version = data + version_bytes_string = [data].pack(OffsetWidth.UINT32) + add_field(MetadataField.new(0x02, 0x01, version_bytes_string)) + end + + # @param creation_time [Integer] - Unix timestamp (required) + def set_creation_time(data) + @creation_time = data + creation_time_bytes_string = [data].pack(OffsetWidth.UINT32) + add_field(MetadataField.new(0x03, 0x01, creation_time_bytes_string)) + end + + def set_expiration_time(data) + @expiration_time = data + expiration_time_bytes_string = [data].pack(OffsetWidth.UINT32) + add_field(MetadataField.new(0x04, 0x01, expiration_time_bytes_string)) + end + + # @param input_uuid_byte_string [String] - Record Time to live (optional) + # if not provided, creates a uuid itself + def set_request_uuid(input_uuid_byte_string = nil) + @request_uuid = if input_uuid_byte_string.nil? + UUIDTools::UUID.random_create + else + UUIDTools::UUID.parse_raw(input_uuid_byte_string) + end + add_field(MetadataField.new(0x05, 0x03, @request_uuid.raw)) + @request_uuid + end + + # SourceInfoField + # @param app_name [String] - Record Time to live (required) + # @param ip [IPAddr] - ip address for component (required) + # @param port [Integer] (required) + def set_source_info(app_name:, ip:, port:) + @ip = ip + @port = port + @app_name = app_name + data = MetadataComponentTemplate::SourceInfoField.new + data.app_name = app_name + data.ip = ip.hton + data.port = port + str_io = StringIO.new + data.write(str_io) + add_field(MetadataField.new(0x06, 0x00, str_io.string)) + end + + def set_last_modification(data) + @last_modification = data + last_modification_bytes_string = [data].pack(OffsetWidth.UINT64) + add_field(MetadataField.new(0x07, 0x02, last_modification_bytes_string)) + end + + # @param input_uuid_byte_string [String] (optional) + # if not provided, creates a uuid itself + def set_originator_request_id(input_uuid_byte_string = nil) + @originator_request_id = if input_uuid_byte_string.nil? + UUIDTools::UUID.random_create + else + UUIDTools::UUID.parse_raw(input_uuid_byte_string) + end + add_field(MetadataField.new(0x08, 0x03, @originator_request_id.raw)) + @originator_request_id + end + + # @param input_uuid_byte_string [String] (optional) + # if not provided, creates a uuid itself + def set_correlation_id(input_uuid_byte_string = nil) + @correlation_id = if input_uuid_byte_string.nil? + UUIDTools::UUID.random_create + else + UUIDTools::UUID.parse_raw(input_uuid_byte_string) + end + field = MetadataComponentTemplate::CorrelationIDField.new + field.correlation_id = @correlation_id.raw + str_io = StringIO.new + field.write(str_io) + # puts field + add_field(MetadataField.new(0x09, 0x0, str_io.string)) + end + + def set_request_handling_time(data) + @request_handling_time = data + request_handling_time_bytes_string = [data].pack(OffsetWidth.UINT32) + add_field(MetadataField.new(0x0A, 0x01, request_handling_time_bytes_string)) + end + + # Function to add feild to the list + # @param field [MetadataField] (required) + def add_field(field) + metadata_field_list.push(field) + end + + # function to calculate size of metadata component + def num_bytes + io = StringIO.new + write(io) + io.size + end + + # Function to serialize Component to buffer + # @param io [StringIO] (required) + def write(io) + buffer = MetadataComponentTemplate.new + buffer.number_of_fields = metadata_field_list.length + metadata_field_list.each do |field| + f = MetadataComponentTemplate::MetadataHeaderField.new + f.size_type = field.size_type + f.field_tag = field.tag + buffer.metadata_fields.push(f) + end + + body = StringIO.new + metadata_field_list.each do |field| + body.write(field.data) + end + padding_size = (8 - body.size % 8) % 8 + body.write(Array.new(0, padding_size).pack(OffsetWidth.UINT8('*'))) if padding_size.positive? + buffer.body = body.string + + buffer.write(io) + end + + # Function to de-serialize Component to buffer + # @param io [StringIO] (required) + def read(io) + metadata_component = MetadataComponentTemplate.new + metadata_component.read(io) + + body_buffer = StringIO.new(metadata_component.body) + + metadata_component.metadata_fields.each do |field| + case field.field_tag + when TagAndType::TimeToLive[:tag] + ttl_byte_string = body_buffer.read(1 << (1 + TagAndType::TimeToLive[:size_type])) + set_time_to_live(ttl_byte_string.unpack1(OffsetWidth.UINT32)) + + when TagAndType::Version[:tag] + version_byte_string = body_buffer.read(1 << (1 + TagAndType::Version[:size_type])) + set_version(version_byte_string.unpack1(OffsetWidth.UINT32)) + + when TagAndType::CreationTime[:tag] + creation_time_byte_string = body_buffer.read(1 << (1 + TagAndType::CreationTime[:size_type])) + set_creation_time(creation_time_byte_string.unpack1(OffsetWidth.UINT32)) + + when TagAndType::RequestUUID[:tag] + request_uuid_byte_string = body_buffer.read(1 << (1 + TagAndType::RequestUUID[:size_type])) + set_request_uuid(request_uuid_byte_string) + + when TagAndType::SourceInfo[:tag] + source_info = MetadataComponentTemplate::SourceInfoField.new + source_info.read(body_buffer) + set_source_info(app_name: source_info.app_name, ip: IPAddr.new_ntoh(source_info.ip), port: source_info.port) + + when TagAndType::LastModification[:tag] + last_modification_byte_string = body_buffer.read(1 << (1 + TagAndType::LastModification[:size_type])) + set_last_modification(last_modification_byte_string.unpack1(OffsetWidth.UINT64)) + + when TagAndType::ExpirationTime[:tag] + expiration_time_byte_string = body_buffer.read(1 << (1 + TagAndType::ExpirationTime[:size_type])) + set_expiration_time(expiration_time_byte_string.unpack1(OffsetWidth.UINT32)) + + when TagAndType::OriginatorRequestID[:tag] + originator_request_id_byte_string = body_buffer.read(1 << (1 + TagAndType::OriginatorRequestID[:size_type])) + set_originator_request_id(originator_request_id_byte_string) + # when TagAndType::CorrelationID[:tag] + + when TagAndType::RequestHandlingTime[:tag] + request_handling_time_byte_string = body_buffer.read(1 << (1 + TagAndType::RequestHandlingTime[:size_type])) + set_request_handling_time(request_handling_time_byte_string.unpack1(OffsetWidth.UINT32)) + end + end + end + + class TagAndType + TimeToLive = { + tag: 0x01, + size_type: 0x01 + }.freeze + Version = { + tag: 0x02, + size_type: 0x01 + }.freeze + CreationTime = { + tag: 0x03, + size_type: 0x01 + }.freeze + RequestUUID = { + tag: 0x05, + size_type: 0x03 + }.freeze + SourceInfo = { + tag: 0x06, + size_type: 0x00 + }.freeze + ExpirationTime = { + tag: 0x04, + size_type: 0x01 + }.freeze + LastModification = { + tag: 0x07, + size_type: 0x02 + }.freeze + OriginatorRequestID = { + tag: 0x08, + size_type: 0x03 + }.freeze + CorrelationID = { + tag: 0x09, + size_type: 0x00 + }.freeze + RequestHandlingTime = { + tag: 0x0A, + size_type: 0x01 + }.freeze + end + + # DataType for @metadata_field_list + class MetadataField + attr_accessor :tag, :size_type, :data + + def initialize(tag, size_type, data) + @tag = tag + @size_type = size_type + @data = data + end + + def size + if size_type == SizeType::Variable + data.length + else + 1 << (size_type + 1) + end + end + + class SizeType + Variable = 0 + end + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/MetadataComponentTemplate.rb b/client/Ruby/juno/lib/juno/IO/MetadataComponentTemplate.rb new file mode 100644 index 00000000..95d19486 --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/MetadataComponentTemplate.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Juno + module IO + class MetadataComponentTemplate < BinData::Record + class MetadataHeaderField < BinData::Record + bit3 :size_type + bit5 :field_tag + end + + class FixedLengthField < BinData::Record + mandatory_parameter :field_length + + string :data, read_length: :field_length + end + + class SourceInfoField < BinData::Record + def field_bytes + field_length.num_bytes + app_name_length.num_bytes + port.num_bytes + ip.num_bytes + app_name.num_bytes + end + + def padding_size + (4 - field_bytes % 4) % 4 + end + + def ipv6? + IPAddr.new_ntoh(ip).ipv6? + end + + endian :big + uint8 :field_length, value: -> { field_bytes + padding.num_bytes } + uint8 :app_name_length, value: -> { ipv6? ? app_name.length | 128 : app_name.length } + uint16 :port + string :ip, read_length: -> { app_name_length & 128 == 1 ? 16 : 4 } + string :app_name, read_length: :app_name_length + string :padding, length: :padding_size + end + + class CorrelationIDField < BinData::Record + def padding_size + size = component_size.num_bytes + correlation_id_length.num_bytes + correlation_id.num_bytes + (4 - size % 4) % 4 + end + + endian :big + uint8 :component_size, value: -> { num_bytes } + uint8 :correlation_id_length, value: -> { correlation_id.length } + string :correlation_id + string :padding, length: :padding_size + end + + def header_num_bytes + component_size.num_bytes + tag_id.num_bytes + number_of_fields.num_bytes + metadata_fields.num_bytes + end + + def header_padding_length + (4 - header_num_bytes % 4) % 4 + end + + endian :big + uint32 :component_size, value: -> { num_bytes } + uint8 :tag_id, value: 0x02 + uint8 :number_of_fields, value: -> { metadata_fields.length } + array :metadata_fields, initial_length: :number_of_fields, type: :metadata_header_field + string :header_padding, length: :header_padding_length # implement padding length + + string :body, read_length: lambda { + component_size - 4 - 1 - 1 - number_of_fields - header_padding.num_bytes + } + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/OperationMessage.rb b/client/Ruby/juno/lib/juno/IO/OperationMessage.rb new file mode 100644 index 00000000..4eba9f08 --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/OperationMessage.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Juno + module IO + class OperationMessage + attr_accessor :protocol_header, :metadata_component, :payload_component + + def initialize + @protocol_header = ProtocolHeader.new + @metadata_component = nil + @payload_component = nil + end + + # Calculates size of message + def size + total_size = protocol_header.num_bytes + total_size += payload_component.num_bytes unless payload_component.nil? + total_size += metadata_component.num_bytes unless metadata_component.nil? + total_size + end + + # Function to serialize message to buffer + # @param io [StringIO] (required) + def write(io) + protocol_header.message_size = size + + protocol_header.write(io) + metadata_component&.write(io) + payload_component&.write(io) + nil + end + + # Function to de-serialize message to buffer + # @param io [StringIO] (required) + def read(io) + return if io.eof? || (io.size - io.pos) < 16 + + @protocol_header = ProtocolHeader.new + @metadata_component = MetadataComponent.new + @payload_component = PayloadComponent.new + + @protocol_header.read(io) + + remaining_size = protocol_header.message_size - 16 + prev_position = io.pos + + @metadata_component.read(io) if !io.eof? && (io.size - io.pos) >= remaining_size + + remaining_size -= (io.pos - prev_position) + + @payload_component.read(io) if !io.eof? && (io.size - io.pos) >= remaining_size + nil + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/PayloadComponent.rb b/client/Ruby/juno/lib/juno/IO/PayloadComponent.rb new file mode 100644 index 00000000..4c2e426f --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/PayloadComponent.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +module Juno + module IO + # ** Payload (or KeyValue) Component ** + # + # A 12-byte header followed by name, key and value + # Tag/ID: 0x01 + # * Header * + # + # |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| + # | 0| 1| 2| 3| + # ------+---------------+---------------+---------------+---------------+ + # 0 | Size | + # ------+---------------+---------------+-------------------------------+ + # 4 | Tag/ID (0x01) | namespace len | key length | + # ------+---------------+---------------+-------------------------------+ + # 8 | payload length | + # ------+---------------------------------------------------------------+ + # + # ( + # The max namespace length: 255 + # payload length = 0 if len(payload data) = 0, otherwise, + # payload length = 1 + len(payload data) = len(payload field) + # ) + # + # + # * Body * + # +---------+-----+---------------+-------------------------+ + # |namespace| key | payload field | Padding to align 8-byte | + # +---------+-----+---------------+-------------------------+ + # + # * Payload field* + # +---------------------+--------------+ + # | 1 byte payload type | Payload data | + # +---------------------+--------------+ + # + # * Payload Type + # 0: payload data is the actual value passed from client user + # 1: payload data is encrypted by Juno client library, details not specified + # 2: payload data is encrypted by Juno proxy with AES-GCM. encryption key length is 256 bits + # 3: Payload data is compressed by Juno Client library. + # + # * Payload data + # for payload type 2 + # +--------------------------------+----------------+----------------+ + # | 4 bytes encryption key version | 12 bytes nonce | encrypted data | + # +--------------------------------+----------------+----------------+ + # + # for payload type 3 + # +---------------------------------+------------------+----------------+ + # | 1 byte size of compression type | compression type | compressed data| + # +---------------------------------+------------------+----------------+ + # + # * compression type + # 1) snappy (default algorithm) + # 2) TBD + class PayloadComponent < BinData::Record + class EncryptedPayloadData < BinData::Record + mandatory_parameter :payload_data_length + end + + class CompressedPayloadData < BinData::Record + mandatory_parameter :payload_data_length + def data_length + eval_parameter(:payload_data_length) - 1 - compression_type + end + + uint8 :compression_type_size, value: -> { :compression_type.length } + string :compression_type, read_length: :compression_type_size, initial_value: CompressionType::None + string :data, read_length: :data_length + end + + # class PayloadBody < BinData::Record + # mandatory_parameter :payload_length + # uint8 :payload_type, initial_value: PayloadType::UnCompressed, only_if: -> { :payload_length.positive? } # optional + + # choice :payload_data, selection: :payload_type, only_if: -> { :payload_length.positive? } do + # compressed_payload_data PayloadType::Compressed, payload_data_length: lambda { + # get_payload_data_length + # } + + # uncompressed_payload_data PayloadType::UnCompressed, payload_data_length: lambda { + # get_payload_data_length + # } + + # encrypted_payload_data PayloadType::Encrypted, payload_data_length: lambda { + # get_payload_data_length + # } + # end + # end + + class UncompressedPayloadData < BinData::Record + mandatory_parameter :payload_data_length + string :data, read_length: :payload_data_length + end + + def get_payload_data_length + (payload_length.positive? ? payload_length - 1 : 0) + end + + # to prevent stack overflow + def custom_num_bytes + size = component_size.num_bytes + tag_id.num_bytes + namespace_length.num_bytes + key_length.num_bytes + payload_length.num_bytes + namespace.num_bytes + payload_key.num_bytes + size += payload_type.num_bytes + payload_data.num_bytes if payload_length.positive? + size + end + + def padding_length + (8 - custom_num_bytes % 8) % 8 + end + + endian :big + uint32 :component_size, value: -> { num_bytes } + uint8 :tag_id, value: 0x01 + uint8 :namespace_length, value: -> { namespace.length } + uint16 :key_length, value: -> { payload_key.length } + uint32 :payload_length, value: -> { payload_data.num_bytes.zero? ? 0 : payload_data.num_bytes + 1 } + string :namespace, read_length: :namespace_length # required + string :payload_key, read_length: :key_length # required + uint8 :payload_type, onlyif: lambda { + payload_length.positive? + }, initial_value: PayloadType::UnCompressed # optional + + choice :payload_data, selection: :payload_type, onlyif: -> { payload_length.positive? } do + compressed_payload_data PayloadType::Compressed, payload_data_length: lambda { + get_payload_data_length + } + + uncompressed_payload_data PayloadType::UnCompressed, payload_data_length: lambda { + get_payload_data_length + } + + encrypted_payload_data PayloadType::Encrypted, payload_data_length: lambda { + get_payload_data_length + } + end + string :padding, length: :padding_length + + def set_value(input_value, compression_type = CompressionType::None) + if compression_type != CompressionType::None + self.payload_type = PayloadType::Compressed + payload_data.compression_type = compression_type + else + self.payload_type = PayloadType::UnCompressed + end + payload_data.data = input_value + end + + def value + payload_data.data + end + + def compressed? + return true if payload_type == PayloadType::Compressed + + false + end + + def compression_type + return payload_data.compression_type if compressed? + + CompressionType::None + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/ProtocolHeader.rb b/client/Ruby/juno/lib/juno/IO/ProtocolHeader.rb new file mode 100644 index 00000000..8229797d --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/ProtocolHeader.rb @@ -0,0 +1,181 @@ +# frozen_string_literal: true + +module Juno + # Juno wire protocol consists of a 12-byte header. Depending on the type, the appropriate message payload follows the fixed header section. Following is the header protocol: + # + # | 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| + # byte | 0| 1| 2| 3| + # ------+-----------------------+-----------------------+-----------------------+-----------------------+ + # 0 | magic | version | message type flag | + # | | +-----------------+-----+ + # | | | type | RQ | + # ------+-----------------------------------------------+-----------------------+-----------------+-----+ + # 4 | message size | + # ------+-----------------------------------------------------------------------------------------------+ + # 8 | opaque | + # ------+-----------------------------------------------------------------------------------------------+ + # + # Following is the detailed description of each field in the header: + # + # offset name size (bytes) meaning + # 0 Magic 2 + # Magic number, used to identify Juno message. + # + # '0x5050' + # + # 2 Version 1 Protocol version, current version is 1. + # 3 Message Type flag + # 1 bit 0-5 + # Message Type + # + # 0: Operational Message + # + # 1: Admin Message + # + # 2: Cluster Control Message + # + # bit 6-7 + # RQ flag + # + # 0: response + # + # 1: two way request + # + # 3: one way request + # + # 4 Message size 4 Specifies the length of the message + # 8 Opaque 4 The Opaque data set in the request will be copied back in the response + # Operational Message + # Client Info (ip, port, type, application name) + # Request Type: request or response + # Operation Type: Create, Get, Update, Delete + # Request Id + # Request Info (key, ttl, version, namespace) + # Payload data size + # Payload + # Response Info (status/error code, error string) + # Flag + # Before defining the details of the protocol for operational message, we need to review, and finalize somethings at page. + # + # Operational Message Header + # + # operational request header + # |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| + # byte | 0| 1| 2| 3| + # ------+---------------+---------------+---------------+---------------+ + # 0 | opcode |flag | shard Id | + # | +-+-------------+ | + # | |R| | | + # ------+---------------+-+-------------+-------------------------------+ + # + # operational response header + # |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| + # byte | 0| 1| 2| 3| + # ------+---------------+---------------+---------------+---------------+ + # 0 | opcode |flag | reserved | status | + # | +-+-------------+ | | + # | |R| | | | + # ------+---------------+-+-------------+---------------+---------------+ + # + # opcode: + # 0x00 Nop + # 0x01 Create + # 0x02 Get + # 0x03 Update + # 0x04 Set + # 0x05 Destroy + # 0x81 PrepareCreate + # 0x82 Read + # 0x83 PrepareUpdate + # 0x84 PrepareSet + # 0x85 PrepareDelete + # 0x86 Delete + # 0xC1 Commit + # 0xC2 Abort (Rollback) + # 0xC3 Repair + # 0xC4 MarkDelete + # 0xE1 Clone + # 0xFE MockSetParam + # oxFF MockReSet + # R: + # 1 if it is for replication + # shard Id: + # only meaning for request to SS + # status: + # 1 byte, only meaningful for response + # + module IO + class ProtocolHeader < BinData::Record + class MessageTypes + OperationalMessage = 0 + AdminMessage = 1 + ClusterControlMessage = 2 + end + + class RequestTypes + Response = 0 + TwoWayRequest = 1 + OneWayRequest = 2 + end + + class OpCodes + Nop = 0x00 + Create = 0x01 + Get = 0x02 + Update = 0x03 + Set = 0x04 + Destroy = 0x05 + PrepareCreate = 0x81 + Read = 0x82 + PrepareUpdate = 0x83 + PrepareSet = 0x84 + PrepareDelete = 0x85 + Delete = 0x86 + Commit = 0xC1 + Abort = 0xC2 + Repair = 0xC3 + MarkDelete = 0xC4 + Clone = 0xE1 + MockSetParam = 0xFE + MockReSet = 0xFF + + def self.valid?(opcode) + constants.each do |constant| + return true if const_get(constant) == opcode + end + false + end + end + + class MessageTypeFlag < BinData::Record + bit2 :message_request_type, initial_value: ProtocolHeader::RequestTypes::TwoWayRequest + bit6 :message_type, initial_value: ProtocolHeader::MessageTypes::OperationalMessage + end + + def request? + message_type_flag.message_request_type != RequestTypes::Response + end + + endian :big + uint16 :magic, value: 0x5050 + uint8 :version, value: 1 + message_type_flag :message_type_flag + uint32 :message_size + uint32 :opaque, initial_value: 0 + uint8 :opcode, initial_value: OpCodes::Nop + uint8 :flag, value: 0 + + uint16 :shard_id, value: 0, onlyif: -> { request? } + uint8 :reserved, onlyif: -> { !request? } + uint8 :status, onlyif: -> { !request? } + + def request_type + message_type_flag.message_request_type + end + + def message_type + message_type_flag.message_type + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/IO/constants.rb b/client/Ruby/juno/lib/juno/IO/constants.rb new file mode 100644 index 00000000..543f24ef --- /dev/null +++ b/client/Ruby/juno/lib/juno/IO/constants.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# Top module for juno client +module Juno + # Submodule containing modules related to WireProtocol + module IO + class OffsetWidth + # Count can be integer or '*' + def self.UINT64(count = '') + "Q#{count}" + end + + def self.UINT32(count = '') + "N#{count}" + end + + def self.UINT16(count = '') + "n#{count}" + end + + def self.UINT8(count = '') + "C#{count}" + end + end + + # Class containing constants for CompressionType + class CompressionType + None = 'None' + Snappy = 'Snappy' + + def self.valid?(compression_type) + constants.each do |constant| + return true if const_get(constant) == compression_type + end + false + end + end + + # Class containing constants for PayloadType + class PayloadType + UnCompressed = 0x00 + Encrypted = 0x02 + Compressed = 0x03 + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/base_processor.rb b/client/Ruby/juno/lib/juno/Net/base_processor.rb new file mode 100644 index 00000000..79c71712 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/base_processor.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Juno + module Net + # BaseProcessor - base class for IOProcessor + # Handles logic for reading and writing ping_ip for bypass ltm + class BaseProcessor + def initialize(_ = nil) + @ping_queue = SizedQueue.new(1) + end + + def ping_ip=(ip) + @ping_queue.push(ip) + end + + def ping_ip + begin + ip = @ping_queue.pop(true) + rescue ThreadError + return nil + end + + return nil if ip.to_s.empty? + + begin + IPAddr.new(ip) + rescue StandardError + nil + end + end + + def clear_ping_queue + @ping_queue.clear + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/client_handler.rb b/client/Ruby/juno/lib/juno/Net/client_handler.rb new file mode 100644 index 00000000..22ecc323 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/client_handler.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module Juno + module Net + # Hanldes connection creation and receiving data asynchronously + # Managed by EventMachine::Connection + class ClientHandler < EventMachine::Connection + # Constant to count messages received + @@recv_count = Concurrent::AtomicFixnum.new(0) + + def self.received_messages + @@recv_count.value + end + + # Constructor + # @param io_processor (Juno::Net::IOProcessor) + def initialize(io_processor) + super + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @io_processor = io_processor + @channel = self + @connected = Concurrent::AtomicBoolean.new(false) + @ssl_connected = Concurrent::AtomicBoolean.new(false) + end + + # Method called once for each instance of Juno::Net::ClientHandler at initialization + def post_init + start_tls_connection if use_ssl? + end + + # starts tls connection once TCP connection is estabilished + def start_tls_connection + raise 'SSL Cert file not found' unless File.exist?(Juno.juno_config.ssl_cert_file) + raise 'SSL Key file not found' unless File.exist?(Juno.juno_config.ssl_key_file) + + @channel.start_tls( + private_key_file: Juno.juno_config.ssl_key_file, cert: File.read(Juno.juno_config.ssl_cert_file) + ) + # Timer to check if SSL Handshake was successful + EventMachine::Timer.new(Juno.juno_config.max_connection_timeout.to_f / 1000) do + if @ssl_connected.false? + puts 'SLL Handshake timeout' + close_connection + end + end + end + + # Method called when TCP connection estabilished. If useSSL is true, it is called after a successfull ssl handshake + def on_connection_completed + # puts "completed #{Time.now}" + end + + # method to check if channel is connected + def is_connected? + if use_ssl? + return false if @ssl_connected.false? + elsif @connected.false? + return false + end + + # get ip and port of server + # Socket.unpack_sockaddr_in(@channel.get_peername) + true + rescue Exception => e + @LOGGER.error(@PROG_NAME) { e.message } + false + end + + def use_ssl? + Juno.juno_config.use_ssl + end + + def use_ltm? + Juno.juno_config.bypass_ltm + end + + # method called by EventMachine when data is received from server + # @param data [String] - byte data received from server + def receive_data(data) + @@recv_count.increment + # puts @@recv_count + + EventMachine.defer do + operation_message = Juno::IO::OperationMessage.new + operation_message.read(StringIO.new(data)) + @io_processor.put_response(operation_message) + end + end + + # Called by EventMachine after TCP Connection estabilished + def connection_completed + @connected.value = true + on_connection_completed unless use_ssl? + end + + # Called by EventMachine after connection disconnected + # @param m - Error if disconnected due to an error + def unbind(error) + @connected.value = false + @ssl_connected.value = false + puts error unless error.nil? + end + + # Called by EventMachine after ssl handshake + def ssl_handshake_completed + @ssl_connected.value = true + on_connection_completed if use_ssl? + + # puts get_cipher_name + # puts get_cipher_protocol + @server_handshake_completed = true + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/io_processor.rb b/client/Ruby/juno/lib/juno/Net/io_processor.rb new file mode 100644 index 00000000..436fc9b4 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/io_processor.rb @@ -0,0 +1,211 @@ +# frozen_string_literal: true + +require 'concurrent' +module Juno + module Net + # Module to handle connections to server, reading/writing requests from request queue + class IOProcessor < BaseProcessor + INITIAL_BYPASSLTM_RETRY_INTERVAL = 337_500 + MAX_BYPASSLTM_RETRY_INTERVAL = 86_400_000 + INIT_WAIT_TIME = 200 + MAX_WAIT_TIME = 60_000 + # class variable to count messages sent using send_data + @@counter = Concurrent::AtomicFixnum.new(0) + def self.send_count + @@counter.value + end + + # @param request_queue [Juno::Net::RequestQueue] + # @param opaque_resp_queue_map [Concurrent::Map] - map containing opaque as key and value as Response queue corresponding to opaque + def initialize(request_queue, opaque_resp_queue_map) + super() + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @stop = false + @request_queue = request_queue + @opaque_resp_queue_map = opaque_resp_queue_map + @ctx = nil ## changed + @handshake_failed_attempts = 0 + @reconnect_wait_time = INIT_WAIT_TIME + @shift = 5 # seconds + @next_bypass_ltm_check_time = Time.now + @bypass_ltm_retry_interval = INITIAL_BYPASSLTM_RETRY_INTERVAL + # @config = config + @channel = nil + @next_reconnect_due = Float::INFINITY + end + + def connection_lifetime + Juno.juno_config.connection_lifetime + end + + def put_response(operation_message) + return if operation_message.nil? + + unless Juno::Net::PingMessage.ping_response?(operation_message, self) + opaque = operation_message&.protocol_header&.opaque + return if opaque.nil? + + resp_queue = @opaque_resp_queue_map.get_and_set(opaque.to_i, nil) + if !resp_queue.nil? + begin + resp_queue.push(operation_message) + rescue ThreadError + @LOGGER.debug(@PROG_NAME) { "response queue for #{opaque.to_i} is full" } + end + else + @LOGGER.debug(@PROG_NAME) { "resp_queue nil for #{opaque.to_i}" } + end + end + nil + end + + def disconnect_channel(channel) + EventMachine::Timer.new(2 * Juno.juno_config.max_response_timeout.to_f / 1000) do + channel&.close_connection_after_writing if !channel.nil? && channel.is_connected? + end + end + + def set_recycle_timer + @recycle_timer = EventMachine::Timer.new(Juno.juno_config.connection_lifetime.to_f / 1000) do + juno_connect(true) + end + end + + def initiate_bypass_ltm + send_ping_message + EventMachine::Timer.new(Juno.juno_config.response_timeout.to_f / 1000) do + ip = ping_ip + unless ip.nil? + new_channel = EventMachine.connect(ip.to_s, Juno.juno_config.port, ClientHandler, self) + EventMachine::Timer.new(Juno.juno_config.connection_timeout.to_f / 1000) do + if new_channel.is_connected? + @LOGGER.info(@PROG_NAME) { "conncected to Proxy #{ip}:#{Juno.juno_config.port} " } + old_channel = @channel + @channel = new_channel + disconnect_channel(old_channel) + else + @LOGGER.info(@PROG_NAME) { "could not conncect to Proxy #{ip}:#{Juno.juno_config.port} " } + end + end + end + end + end + + # Sends ping message to LoadBalancer to get ProxyIP + # @see Juno::Net::PingMessage + def send_ping_message + ping_message = Juno::Net::PingMessage.new + buff = StringIO.new + ping_message.write(buff) + request_uuid = ping_message&.operation_message&.metadata_component&.request_uuid.to_s + @request_queue.push(buff.string, request_uuid) + end + + # Method to handle connections creation, re-attempts on failure, initiates connection refresh and connection to Proxy + # @param recycle [Boolean] - True if connection refresh request (optional, default: false) + def juno_connect(recycle = false) + return if !recycle && !@channel.nil? && @channel.is_connected? + + new_channel = EventMachine.connect(Juno.juno_config.host, Juno.juno_config.port, ClientHandler, self) + new_channel.pending_connect_timeout = Juno.juno_config.connection_lifetime + EventMachine::Timer.new(Juno.juno_config.connection_timeout.to_f / 1000) do + if new_channel.is_connected? + @LOGGER.info(@PROG_NAME) { "conncected to #{Juno.juno_config.host}:#{Juno.juno_config.port} " } + if recycle + old_channel = @channel + @channel = new_channel + disconnect_channel(old_channel) + else + @channel = new_channel + end + initiate_bypass_ltm if use_ltm? + set_recycle_timer + else + @recycle_timer&.cancel + new_channel&.close_connection if !new_channel.nil? && new_channel.is_connected? + @LOGGER.info(@PROG_NAME) do + "Could not conncect to #{Juno.juno_config.host}:#{Juno.juno_config.port}\n Retrying in #{@reconnect_wait_time.to_f / 1000}ms " + end + EventMachine::Timer.new(@reconnect_wait_time.to_f / 1000) do + @reconnect_wait_time *= 2 + @reconnect_wait_time = MAX_WAIT_TIME if @reconnect_wait_time > MAX_WAIT_TIME + @reconnect_wait_time *= (1 + 0.3 * rand) + juno_connect(recycle) + end + end + end + end + + def stop + @stop = true + end + + # Event loop to continously check for requests in @request_queue + def run + EventMachine.run do + juno_connect + EventMachine.tick_loop do + if !@channel.nil? && @channel.is_connected? + # key = "19key#{rand(100) + rand(1_000_000)}" + item = @request_queue.pop + unless item.nil? + @@counter.increment + @channel.send_data(item.msg_buffer) + end + end + :stop if @stop == true + rescue Exception => e + @LOGGER.error(@PROG_NAME) do + "Error in tick_loop: #{e.message}. Stopping tick_loop" + end + :stop + end.on_stop do + @LOGGER.debug(@PROG_NAME) do + "tick loop stopped. Stop initiated by client #{@stop}" + end + reset_connections + EventMachine::Timer.new(2 * Juno.juno_config.connection_timeout.to_f / 1000) do + EventMachine.stop + end + end + rescue Exception => e + @LOGGER.debug(@PROG_NAME) do + "EventMachine Fatal Exception #{e.message}" + end + reset_connections + EventMachine.stop + end + end + + def reset_connections + @recycle_timer&.cancel + disconnect_channel(@channel) + end + + def use_ssl? + Juno.juno_config.use_ssl + end + + def host + Juno.juno_config.host + end + + def port + Juno.juno_config.port + end + + def use_ltm? + host != '127.0.0.1' && Juno.juno_config.bypass_ltm # boolean + end + + def bypass_ltm_disabled? + if Time.now > @next_bypass_ltm_check_time && @bypass_ltm_retry_interval < MAX_BYPASSLTM_RETRY_INTERVAL + return false + end + + true + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/ping_message.rb b/client/Ruby/juno/lib/juno/Net/ping_message.rb new file mode 100644 index 00000000..6d060602 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/ping_message.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Juno + module Net + # Module to Create/Decode Ping messages + class PingMessage + # Constant Internal app name to check for ping messages + JUNO_INTERNAL_APPNAME = 'JunoInternal' + + # method to read the operation message + attr_reader :operation_message + + # @param operation_message [Juno::IO::OperationMessage] (optional, default: Juno::Net::PingMessage::JUNO_INTERNAL_APPNAME) + # @param opaque [Integer] (optional, default: 0) + def initialize(app_name = nil, opaque = 0) + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + app_name = JUNO_INTERNAL_APPNAME if app_name.to_s.empty? + + meta_data_component = Juno::IO::MetadataComponent.new + meta_data_component.set_request_uuid + meta_data_component.set_source_info(app_name: app_name, ip: IPAddr.new(Juno::Utils.local_ips[0]), port: 0) + + protocol_header = Juno::IO::ProtocolHeader.new + protocol_header.opcode = Juno::IO::ProtocolHeader::OpCodes::Nop + protocol_header.opaque = opaque + + @operation_message = Juno::IO::OperationMessage.new + @operation_message.metadata_component = meta_data_component + @operation_message.protocol_header = protocol_header + end + + # method to check if given operation message is a Ping response + # Updates ping_ip in processor if it is a ping response + # @param operation_message [Juno::IO::OperationMessage] (required) + # @param operation_message [Juno::Net::IOProcessor] (required) + def self.ping_response?(operation_message, processor) + return false unless processor.use_ltm? + + opcode = operation_message&.protocol_header&.opcode + raise 'missing protocol header' if opcode.nil? + return false if opcode != Juno::IO::ProtocolHeader::OpCodes::Nop + return false if operation_message&.metadata_component.nil? + return false if operation_message&.metadata_component&.ip.to_s.empty? + return false if operation_message&.metadata_component&.app_name != JUNO_INTERNAL_APPNAME + + ping_ip = operation_message.metadata_component.ip.to_s + if ping_ip.split('.')[0] == '127' + processor.ping_ip = '' + return true + end + if Juno::Utils.local_ips.include?(ping_ip) + processor.ping_ip = '' + return true + end + processor.ping_ip = ping_ip + true + end + + # Function to serialize Component to buffer + # @param buff [StringIO] (required) + def write(buf) + @operation_message.write(buf) + end + + # Function to de-serialize Component from buffer + # @param buff [StringIO] (required) + def read(buf) + @operation_message = Juno::IO::OperationMessage.new + @operation_message.read(buf) + end + + # Function to read the ping ip + def ip + @operation_message&.metadata_component&.ip + end + + # Function to read the port from metadata component + def port + @operation_message&.metadata_component&.port + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/request_queue.rb b/client/Ruby/juno/lib/juno/Net/request_queue.rb new file mode 100644 index 00000000..4b62093c --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/request_queue.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module Juno + module Net + # DataType of each item in RequestQueue + class QueueEntry + attr_accessor :msg_buffer, :req_id, :enqueue_time + + # @param msg_bugger [StringIO] (required) + # @param id [String] - request UUID (required) + def initialize(msg_buffer, id) + @msg_buffer = msg_buffer + @req_id = id + @enqueue_time = Time.now + end + end + + # Request queue - Singleton + class RequestQueue + # mutex to synchronize creation of RequestQueue instance + @@mutex = Mutex.new + + # Singleton instance + @@instance = nil + + def self.instance + return @@instance unless @@instance.nil? + + @@mutex.synchronize do + @@instance ||= new + end + end + + private_class_method :new + + attr_reader :opaque_resp_queue_map + + def initialize + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @size = 13_000 # Default request queue size + @request_queue = SizedQueue.new(@size) + @opaque_resp_queue_map = Concurrent::Map.new + @worker_pool = Juno::Net::WorkerPool.new(self) + end + + def full? + @request_queue.size == @size + end + + def size + @request_queue.size + end + + def stop + @worker_pool.stop + @request_queue.clear + end + + # @param operation_message [Juno::IO::OperatioinMessage] (required) + # @return [Boolean] - true if successfully pushed item to queue. Else false + def push(msg_buffer, request_uuid) + # buffer = StringIO.new + # operation_message.write(buffer) + # request_uuid = operation_message&.metadata_component&.request_uuid.to_s + request_uuid = 'not_set' if request_uuid.to_s.empty? + + begin + @request_queue.push(QueueEntry.new(msg_buffer, request_uuid), true) + rescue ThreadError + return false + end + true + end + + # @return [QueueEntry] - nil if queue empty + def pop + @request_queue.pop(true) + rescue ThreadError + # queue empty + nil + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Net/worker_pool.rb b/client/Ruby/juno/lib/juno/Net/worker_pool.rb new file mode 100644 index 00000000..a94c6923 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Net/worker_pool.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Juno + module Net + class WorkerPool + def initialize(request_queue) + raise 'Request queue cannot be nil' if request_queue.nil? + + @PROG_NAME = self.class.name + @LOGGER = Juno::Logger.instance + @request_queue = request_queue + EventMachine.threadpool_size = 200 + @io_processor = Juno::Net::IOProcessor.new(@request_queue, @request_queue.opaque_resp_queue_map) + init + end + + def init + @worker = Thread.new do + @io_processor.run + end + end + + def active? + @worker.alive? + end + + def stop + @io_processor.stop + end + end + end +end diff --git a/client/Ruby/juno/lib/juno/Utils/client_utils.rb b/client/Ruby/juno/lib/juno/Utils/client_utils.rb new file mode 100644 index 00000000..ae10f05a --- /dev/null +++ b/client/Ruby/juno/lib/juno/Utils/client_utils.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module Juno + module ClientUtils + def self.create_operation_message(juno_message, opaque) + protocol_header = Juno::IO::ProtocolHeader.new + protocol_header.version = juno_message.version + protocol_header.opcode = juno_message.operation_type + protocol_header.opaque = opaque + + metadata_component = Juno::IO::MetadataComponent.new + if juno_message.time_to_live_s.to_i.positive? + metadata_component.set_time_to_live(juno_message.time_to_live_s.to_i) + end + metadata_component.set_version(juno_message.version) + + if [Juno::IO::JunoMessage::OperationType::CREATE, + Juno::IO::JunoMessage::OperationType::SET].include?(juno_message.operation_type) + metadata_component.set_creation_time(Time.now.to_i) + end + + metadata_component.set_expiration_time((Time.now + juno_message.time_to_live_s).to_i) # what ? + metadata_component.set_request_uuid(juno_message.request_uuid) + metadata_component.set_source_info(app_name: juno_message.app_name, ip: juno_message.ip, port: juno_message.port) + metadata_component.set_originator_request_id # what + + payload_component = Juno::IO::PayloadComponent.new + payload_component.namespace = juno_message.namespace + payload_component.payload_key = juno_message.key + payload_component.set_value(juno_message.value, juno_message.compression_type) + + operation_message = Juno::IO::OperationMessage.new + operation_message.protocol_header = protocol_header + operation_message.metadata_component = metadata_component + operation_message.payload_component = payload_component + + juno_message.message_size = operation_message.size + + operation_message + end + + def self.compressed_value(value) + compressed_value = Snappy.deflate(value) + compression_achieved = 100 - (compressed_value.length * 100) / value.length + [compressed_value, compression_achieved] + rescue Exception + [value, false] + end + + def self.decompress_value(value) + Snappy.inflate(value) + rescue Exception + # Log failure + value + end + + def self.validate!(juno_request) + return false unless juno_request.is_a?(Juno::Client::JunoRequest) + + raise ArgumentError, 'Juno request key cannot be empty' if juno_request.key.to_s.nil? + + juno_request.time_to_live_s = Juno.juno_config.default_lifetime unless juno_request.time_to_live_s.to_i.positive? + + if juno_request.time_to_live_s > Juno.juno_config.max_lifetime || juno_request.time_to_live_s.negative? + raise ArgumentError, + "Record time_to_live_s (#{juno_request.time_to_live_s}s) cannot be greater than #{Juno.juno_config.max_lifetime}s or negative ." + end + + if juno_request.key.to_s.size > Juno.juno_config.max_key_size + raise ArgumentError, + "Key size cannot be greater than #{Juno.juno_config.max_key_size}" + end + + if juno_request.key.to_s.size > Juno.juno_config.max_key_size + raise ArgumentError, + "Key size cannot be greater than #{Juno.juno_config.max_key_size}" + end + + juno_message = Juno::IO::JunoMessage.new + juno_message.key = juno_request.key + juno_message.version = juno_request.version + juno_message.operation_type = juno_request.type + juno_message.time_to_live_s = juno_request.time_to_live_s + juno_message.creation_time = juno_request.creation_time + juno_message.namespace = Juno.juno_config.record_namespace + juno_message.app_name = Juno.juno_config.app_name + juno_message.request_uuid = UUIDTools::UUID.random_create.to_s + juno_message.ip = IPAddr.new(Juno::Utils.local_ips[0]) + juno_message.port = 0 + + unless [Juno::Client::JunoRequest::Type::GET, + Juno::Client::JunoRequest::Type::DESTROY].include?(juno_request.type) + payload_value = juno_request.value + is_compressed = false + compression_achieved = 0 + if Juno.juno_config.use_payload_compression && value.length > 1024 + payload_value, compression_achieved = compressed_value(value) + is_compressed = true if compression_achieved.positive? + end + juno_message.is_compressed = is_compressed + juno_message.value = payload_value + juno_message.compression_achieved = compression_achieved + juno_message.compression_type = is_compressed ? Juno::IO::CompressionType::Snappy : Juno::IO::CompressionType::None + end + + juno_message + end + + # @params operation_message [Juno::IO::OperationMessage] (required) + # @returns [Juno::IO::JunoMessage] + def self.decode_operation_message(operation_message) + return nil unless operation_message.is_a?(Juno::IO::OperationMessage) + + juno_message = Juno::IO::JunoMessage.new + opcode = operation_message.protocol_header.opcode.to_i + juno_message.operation_type = Juno::IO::JunoMessage::OperationType.get(opcode) + + server_status = operation_message.protocol_header.status.to_i + juno_message.server_status = Juno::ServerStatus.get(server_status) + + juno_message.message_size = operation_message.protocol_header.message_size.to_i + + unless operation_message.metadata_component.nil? + metadata_component = operation_message.metadata_component + juno_message.time_to_live_s = metadata_component.time_to_live.to_i + juno_message.ip = metadata_component.ip + juno_message.port = metadata_component.port + juno_message.version = metadata_component.version.to_i + juno_message.creation_time = metadata_component.creation_time.to_i + juno_message.expiration_time = metadata_component.expiration_time.to_i + juno_message.request_uuid = metadata_component.request_uuid + juno_message.app_name = metadata_component.app_name + juno_message.last_modification = metadata_component.last_modification.to_i + juno_message.originator_request_id = metadata_component.originator_request_id.to_s + juno_message.correlation_id = metadata_component.correlation_id + juno_message.request_handling_time = metadata_component.request_handling_time.to_i + # juno_message.request_start_time = metadata_component. + # expiry + end + + unless operation_message.payload_component.nil? + juno_message.namespace = operation_message.payload_component.namespace.to_s + juno_message.key = operation_message.payload_component.payload_key.to_s + juno_message.is_compressed = operation_message.payload_component.compressed? + juno_message.compression_type = operation_message.payload_component.compression_type.to_i + juno_message.value = if operation_message.payload_component.payload_length.to_i.zero? + juno_message.compression_achieved = 0 + nil + elsif juno_message.is_compressed + compressed_value = operation_message.payload_component.value.to_s + decompressed_value = decompress_value(compressed_value) + juno_message.compression_achieved = 100 - (compressed_value.length / decompressed_value.length.to_f) * 100.0 + decompressed_value + else + juno_message.compression_achieved = 0 + operation_message.payload_component.value.to_s + end + end + + juno_message + end + end +end diff --git a/client/Ruby/juno/lib/juno/Utils/utils.rb b/client/Ruby/juno/lib/juno/Utils/utils.rb new file mode 100644 index 00000000..f9da34d0 --- /dev/null +++ b/client/Ruby/juno/lib/juno/Utils/utils.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +module Juno + class Utils + def self.local_ips + ip_addresses = Socket.ip_address_list.select do |addr| + addr.ipv4? && !addr.ipv4_loopback? # && !addr.ipv4_private? + end + ip_addresses.map!(&:ip_address) + rescue StandardError => e + puts e.message + ['127.0.0.1'] + end + + def self.create_message(key, op_type, value = '') + meta_data_component = Juno::IO::MetadataComponent.new + # ip = IPAddr.new(Socket.ip_address_list.detect(&:ipv4_private?).ip_address) + meta_data_component.set_time_to_live(Juno.juno_config.default_lifetime) + meta_data_component.set_version(1) + meta_data_component.set_creation_time(1000) + meta_data_component.set_request_uuid + meta_data_component.set_correlation_id + meta_data_component.set_originator_request_id + meta_data_component.set_source_info(app_name: Juno.juno_config.app_name, ip: IPAddr.new(Juno::Utils.local_ips[0]), + port: Juno.juno_config.port) + + payload_component = Juno::IO::PayloadComponent.new + payload_component.namespace = Juno.juno_config.record_namespace + payload_component.payload_key = key + if op_type == Juno::IO::ProtocolHeader::OpCodes::Create && !value.to_s.empty? + is_compressed = false + if Juno.juno_config.use_payload_compression && value.length > 1024 + value, compression_achieved = compressed_value(value) + is_compressed = true if compression_achieved.positive? + end + if is_compressed + puts 'using compression' + payload_component.set_value(value, Juno::IO::CompressionType::Snappy) + else + payload_component.set_value(value) + end + end + + protocol_header = Juno::IO::ProtocolHeader.new + protocol_header.opcode = op_type + + operation_message = Juno::IO::OperationMessage.new + operation_message.metadata_component = meta_data_component + operation_message.protocol_header = protocol_header + operation_message.payload_component = payload_component + buffer = StringIO.new + operation_message.write(buffer) + buffer + end + + def self.ssl_context + ssl_context = OpenSSL::SSL::SSLContext.new + ssl_context.ssl_version = :TLSv1_1 + cert = OpenSSL::X509::Certificate.new(File.open(File.expand_path(File.join( + __dir__, '..', '..', 'server.crt' + )))) + key = OpenSSL::PKey::RSA.new(File.open(File.expand_path(File.join( + __dir__, '..', '..', 'server.pem' + )))) + ca_file = OpenSSL::X509::Certificate.new(File.open(File.expand_path(File.join( + __dir__, '..', '..', 'myca.crt' + )))) + ssl_context.add_certificate(cert, key, [ca_file]) + # ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER + ssl_context.ssl_timeout = 10 + ssl_context.timeout = 10 + ssl_context + end + + def self.ssl_request(buffer) + socket = TCPSocket.open(Juno.juno_config.host, Juno.juno_config.port) + if Juno.juno_config.use_ssl + ctx = ssl_context + socket = OpenSSL::SSL::SSLSocket.new(socket, ctx) + socket.sync_close = true + # socket.post_connection_check(Juno.juno_config.host) + socket.connect + end + + # puts socket.peer_finished_message.bytes.join(', ') + # puts socket.verify_result + + socket.write(buffer.string) + res_buffer = StringIO.new + header = true + + size = 0 + while (line = socket.sysread(1024 * 16)) # buffer size of OpenSSL library + if header + p = Juno::IO::ProtocolHeader.new + p.read(StringIO.new(line)) + header = false + size = p.message_size + end + res_buffer.write(line) + break if res_buffer.length == size + end + socket.close + + res_buffer.rewind + + res_buffer + end + + def self.create_and_send_ping_message + ping_message = Juno::Net::PingMessage.new + ping_buffer = StringIO.new + ping_message.write(ping_buffer) + response = ssl_request(ping_buffer) + ping_message = Juno::Net::PingMessage.new + ping_message.read(response) + ping_message + end + + def self.time_diff_ms(a, b) + (b - a).abs * 1000 + end + end +end diff --git a/client/Ruby/juno/lib/juno/logger.rb b/client/Ruby/juno/lib/juno/logger.rb new file mode 100644 index 00000000..6e0ef7e7 --- /dev/null +++ b/client/Ruby/juno/lib/juno/logger.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Juno + # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN + + class Logger + @@mutex = Mutex.new + + # Singleton instance + @@instance = nil + + def self.instance + return @@instance unless @@instance.nil? + + @@mutex.synchronize do + if @@instance.nil? + raise 'log file not configured' if Juno.juno_config.log_file.to_s.empty? + + @@instance = ::Logger.new(Juno.juno_config.log_file, 'daily', progname: 'JunoRubyClient') + + @@instance.level = ::Logger::INFO + end + end + @@instance + end + + def self.level=(log_level) + @@instance.level = log_level unless @@instance.nil? + end + + private_class_method :new + end +end diff --git a/client/Ruby/juno/lib/juno/server_status.rb b/client/Ruby/juno/lib/juno/server_status.rb new file mode 100644 index 00000000..a5af05d2 --- /dev/null +++ b/client/Ruby/juno/lib/juno/server_status.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Juno + class ServerStatus + SUCCESS = { code: 0, error_msg: 'no error', client_operation_status: Juno::Client::OperationStatus::SUCCESS }.freeze + BAD_MSG = { code: 1, error_msg: 'bad message', + client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze + NO_KEY = { code: 3, error_msg: 'key not found', + client_operation_status: Juno::Client::OperationStatus::NO_KEY }.freeze + DUP_KEY = { code: 4, error_msg: 'dup key', + client_operation_status: Juno::Client::OperationStatus::UNIQUE_KEY_VIOLATION }.freeze + BAD_PARAM = { code: 7, error_msg: 'bad parameter', + client_operation_status: Juno::Client::OperationStatus::BAD_PARAM }.freeze + RECORD_LOCKED = { code: 8, error_msg: 'record locked', + client_operation_status: Juno::Client::OperationStatus::RECORD_LOCKED }.freeze + NO_STORAGE_SERVER = { code: 12, error_msg: 'no active storage server', + client_operation_status: Juno::Client::OperationStatus::NO_STORAGE }.freeze + SERVER_BUSY = { code: 14, error_msg: 'Server busy', + client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze + VERSION_CONFLICT = { code: 19, error_msg: 'version conflict', + client_operation_status: Juno::Client::OperationStatus::CONDITION_VIOLATION }.freeze + OP_STATUS_SS_READ_TTL_EXTENDERR = { code: 23, error_msg: 'Error extending TTL by SS', + client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze + COMMIT_FAILURE = { code: 25, error_msg: 'Commit Failure', + client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze + INCONSISTENT_STATE = { code: 26, error_msg: 'Inconsistent State', + client_operation_status: Juno::Client::OperationStatus::SUCCESS }.freeze + INTERNAL = { code: 255, error_msg: 'Internal error', + client_operation_status: Juno::Client::OperationStatus::INTERNAL_ERROR }.freeze + + @@status_code_map = nil + + def self.initialize_map + @@status_code_map = {} + + constants.each do |const| + const_obj = const_get(const) + @@status_code_map[const_obj[:code].to_i] = const_obj + end + end + + def self.get(status_code) + initialize_map if @@status_code_map.nil? + return @@status_code_map[status_code] if @@status_code_map.key?(status_code.to_i) + + INTERNAL + end + end +end diff --git a/client/Ruby/juno/lib/juno/version.rb b/client/Ruby/juno/lib/juno/version.rb new file mode 100644 index 00000000..e9bf587c --- /dev/null +++ b/client/Ruby/juno/lib/juno/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Juno + VERSION = '1.0.0' +end diff --git a/client/Ruby/juno/pkg/juno-0.1.0.gem b/client/Ruby/juno/pkg/juno-0.1.0.gem new file mode 100644 index 00000000..90a4f1c9 Binary files /dev/null and b/client/Ruby/juno/pkg/juno-0.1.0.gem differ diff --git a/client/Ruby/juno/pkg/juno-1.0.0.gem b/client/Ruby/juno/pkg/juno-1.0.0.gem new file mode 100644 index 00000000..06f03990 Binary files /dev/null and b/client/Ruby/juno/pkg/juno-1.0.0.gem differ diff --git a/client/Ruby/juno/spec/Client/sync_client.rb b/client/Ruby/juno/spec/Client/sync_client.rb new file mode 100644 index 00000000..aaf3846c --- /dev/null +++ b/client/Ruby/juno/spec/Client/sync_client.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'juno' + +describe 'Sync client tests' do + before(:context) do + Juno.configure do |config| + config.file_path = URI.join('file:///', File.expand_path('./../../../juno.yml').to_s) + config.log_file = 'juno.log' + config.ssl_cert_file = File.expand_path('./../../lib/server.crt') + config.ssl_key_file = File.expand_path('./../../lib/server.pem') + end + + @juno_client = Juno::Client::SyncClient.new + @key = "mykey#{rand(1000)}" + @value = 'myvalue' + end + + it 'create test' do + juno_resp = @juno_client.create(@key, @value, ttl: 12_000) + expect(juno_resp.status[:code]).to eq(Juno::ServerStatus::SUCCESS[:code]) + expect(juno_resp.record_context.time_to_live_s).to eq(12_000) + end + + it 'get request test' do + juno_resp = @juno_client.get(@key) + expect(juno_resp.status[:code]).to eq(Juno::ServerStatus::SUCCESS[:code]) + expect(juno_resp.value).to eq(@value) + expect(juno_resp.record_context.version).to eq(1) + end + + it 'update request test' do + juno_resp = @juno_client.update(@key, 'newvalue') + @record_context = juno_resp.record_context + expect(juno_resp.status[:code]).to eq(Juno::ServerStatus::SUCCESS[:code]) + expect(juno_resp.value).to eq(@value) + expect(juno_resp.record_context.version).to eq(1) + end + + it 'compare_and_set request test' do + juno_resp = @juno_client.compare_and_set(@record_context, 'value99') + expect(juno_resp.status[:code]).to eq(Juno::ServerStatus::SUCCESS[:code]) + expect(juno_resp.value).to eq(@value) + expect(juno_resp.record_context.version).to eq(1) + end +end diff --git a/client/Ruby/juno/spec/IO/metadata_component.rb b/client/Ruby/juno/spec/IO/metadata_component.rb new file mode 100644 index 00000000..16f40803 --- /dev/null +++ b/client/Ruby/juno/spec/IO/metadata_component.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +require 'bindata' +require_relative '../../lib/juno/IO/constants' +require_relative '../../lib/juno/IO/MetadataComponentTemplate' +require_relative '../../lib/juno/IO/MetadataComponent' + +describe 'Juno::IO::PayloadComponent buffer write' do + before(:context) do + @payload = Juno::IO::MetadataComponent.new + @NAMESPACE = 'testnamespace123' + @KEY = 'testkey123' + @VALUE = 'testvalue456' + + @payload.payload_key = @KEY # length: 10 + @payload.namespace = @NAMESPACE # length: 16 + @payload.set_value(@VALUE) # length: 12 + # size = 13 + 10 + 16 + 12 + 5 = 56 + buff = StringIO.new + @payload.write(buff) + + @bytes_arr = buff.string.bytes + end + + it 'component size should be 56' do + expect(@bytes_arr.length).to eq(56) + size = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(@payload.component_size).to eq(56) + expect(size).to eq(56) + end + + it 'tag_id should be 1' do + expect(@payload.tag_id).to eq(1) + expect(@bytes_arr.shift).to eq(1) + end + + it 'namspace_length should be 16' do + expect(@payload.namespace_length).to eq(16) + expect(@bytes_arr.shift).to eq(16) + end + + it 'key_length should be 10' do + key_length = @bytes_arr.shift(2).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT16) + expect(@payload.key_length).to eq(10) + expect(key_length).to eq(10) + end + + it 'payload_length should be 13' do + payload_length = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(@payload.payload_length).to eq(13) + expect(payload_length).to eq(13) + end + + it 'namespace as expected' do + namespace = @bytes_arr.shift(@NAMESPACE.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.namespace).to eq(@NAMESPACE) + expect(namespace).to eq(@NAMESPACE) + end + + it 'key as expected' do + key = @bytes_arr.shift(@KEY.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.payload_key).to eq(@KEY) + expect(key).to eq(@KEY) + end + + it 'payload_type should be Juno::IO::PayloadType::UnCompressed' do + ptype = @bytes_arr.shift + expect(@payload.payload_type).to eq(Juno::IO::PayloadType::UnCompressed) + expect(ptype).to eq(Juno::IO::PayloadType::UnCompressed) + end + + it 'payload value expected' do + value = @bytes_arr.shift(@VALUE.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.value).to eq(@VALUE) + expect(value).to eq(@VALUE) + end + + it 'payload length' do + padding = @bytes_arr.shift(5).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(padding.length).to eq(5) + expect(@payload.padding.length).to eq(5) + expect(padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + expect(@payload.padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + end +end + +describe 'Juno::IO::PayloadComponent buffer read' do + before(:context) do + @payload = Juno::IO::PayloadComponent.new + @NAMESPACE = 'testnamespace123' # length: 16 + @KEY = 'testkey123' # length: 10 + @VALUE = 'testvalue456' # length: 12 + + # size = 13 + 10 + 16 + 12 + 5 = 56 + buff = StringIO.new("\x00\x00\x008\x01\x10\x00\n\x00\x00\x00\rtestnamespace123testkey123\x00testvalue456\x00\x00\x00\x00\x00") + @payload.read(buff) + end + + it 'component size should be 56' do + expect(@payload.component_size).to eq(56) + end + + it 'tag_id should be 1' do + expect(@payload.tag_id).to eq(1) + end + + it 'namspace_length should be 16' do + expect(@payload.namespace_length).to eq(16) + end + + it 'key_length should be 10' do + expect(@payload.key_length).to eq(10) + end + + it 'payload_length should be 13' do + expect(@payload.payload_length).to eq(13) + end + + it 'namespace as expected' do + expect(@payload.namespace).to eq(@NAMESPACE) + end + + it 'key as expected' do + expect(@payload.payload_key).to eq(@KEY) + end + + it 'payload_type should be Juno::IO::PayloadType::UnCompressed' do + expect(@payload.payload_type).to eq(Juno::IO::PayloadType::UnCompressed) + end + + it 'payload value expected' do + expect(@payload.value).to eq(@VALUE) + end + + it 'payload length' do + expect(@payload.padding.length).to eq(5) + expect(@payload.padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + end +end diff --git a/client/Ruby/juno/spec/IO/payload_component_spec.rb b/client/Ruby/juno/spec/IO/payload_component_spec.rb new file mode 100644 index 00000000..d064f783 --- /dev/null +++ b/client/Ruby/juno/spec/IO/payload_component_spec.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +require 'juno' + +describe 'Juno::IO::PayloadComponent buffer write' do + before(:context) do + @payload = Juno::IO::PayloadComponent.new + @NAMESPACE = 'testnamespace123' + @KEY = 'testkey123' + @VALUE = 'testvalue456' + + @payload.payload_key = @KEY # length: 10 + @payload.namespace = @NAMESPACE # length: 16 + @payload.set_value(@VALUE) # length: 12 + # size = 13 + 10 + 16 + 12 + 5 = 56 + buff = StringIO.new + @payload.write(buff) + + @bytes_arr = buff.string.bytes + end + + it 'component size should be 56' do + expect(@bytes_arr.length).to eq(56) + size = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(@payload.component_size).to eq(56) + expect(size).to eq(56) + end + + it 'tag_id should be 1' do + expect(@payload.tag_id).to eq(1) + expect(@bytes_arr.shift).to eq(1) + end + + it 'namspace_length should be 16' do + expect(@payload.namespace_length).to eq(16) + expect(@bytes_arr.shift).to eq(16) + end + + it 'key_length should be 10' do + key_length = @bytes_arr.shift(2).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT16) + expect(@payload.key_length).to eq(10) + expect(key_length).to eq(10) + end + + it 'payload_length should be 13' do + payload_length = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(@payload.payload_length).to eq(13) + expect(payload_length).to eq(13) + end + + it 'namespace as expected' do + namespace = @bytes_arr.shift(@NAMESPACE.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.namespace).to eq(@NAMESPACE) + expect(namespace).to eq(@NAMESPACE) + end + + it 'key as expected' do + key = @bytes_arr.shift(@KEY.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.payload_key).to eq(@KEY) + expect(key).to eq(@KEY) + end + + it 'payload_type should be Juno::IO::PayloadType::UnCompressed' do + ptype = @bytes_arr.shift + expect(@payload.payload_type).to eq(Juno::IO::PayloadType::UnCompressed) + expect(ptype).to eq(Juno::IO::PayloadType::UnCompressed) + end + + it 'payload value expected' do + value = @bytes_arr.shift(@VALUE.length).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(@payload.value).to eq(@VALUE) + expect(value).to eq(@VALUE) + end + + it 'payload length' do + padding = @bytes_arr.shift(5).pack(Juno::IO::OffsetWidth.UINT8('*')) + expect(padding.length).to eq(5) + expect(@payload.padding.length).to eq(5) + expect(padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + expect(@payload.padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + end +end + +describe 'Juno::IO::PayloadComponent buffer read' do + before(:context) do + @payload = Juno::IO::PayloadComponent.new + @NAMESPACE = 'testnamespace123' # length: 16 + @KEY = 'testkey123' # length: 10 + @VALUE = 'testvalue456' # length: 12 + + # size = 13 + 10 + 16 + 12 + 5 = 56 + buff = StringIO.new("\x00\x00\x008\x01\x10\x00\n\x00\x00\x00\rtestnamespace123testkey123\x00testvalue456\x00\x00\x00\x00\x00") + @payload.read(buff) + end + + it 'component size should be 56' do + expect(@payload.component_size).to eq(56) + end + + it 'tag_id should be 1' do + expect(@payload.tag_id).to eq(1) + end + + it 'namspace_length should be 16' do + expect(@payload.namespace_length).to eq(16) + end + + it 'key_length should be 10' do + expect(@payload.key_length).to eq(10) + end + + it 'payload_length should be 13' do + expect(@payload.payload_length).to eq(13) + end + + it 'namespace as expected' do + expect(@payload.namespace).to eq(@NAMESPACE) + end + + it 'key as expected' do + expect(@payload.payload_key).to eq(@KEY) + end + + it 'payload_type should be Juno::IO::PayloadType::UnCompressed' do + expect(@payload.payload_type).to eq(Juno::IO::PayloadType::UnCompressed) + end + + it 'payload value expected' do + expect(@payload.value).to eq(@VALUE) + end + + it 'payload length' do + expect(@payload.padding.length).to eq(5) + expect(@payload.padding).to eq([0, 0, 0, 0, 0].pack(Juno::IO::OffsetWidth.UINT8('*'))) + end +end diff --git a/client/Ruby/juno/spec/IO/protocol_header_spec.rb b/client/Ruby/juno/spec/IO/protocol_header_spec.rb new file mode 100644 index 00000000..b64a02e0 --- /dev/null +++ b/client/Ruby/juno/spec/IO/protocol_header_spec.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'juno' + +describe 'Juno::IO::ProtocolHeader buffer write' do + before(:context) do + @header = Juno::IO::ProtocolHeader.new + @header.message_size = 16 + @header.opaque = 12 + buff = StringIO.new + @header.write(buff) + @bytes_arr = buff.string.bytes + end + + it 'number of bytes should be 16' do + expect(@bytes_arr.size).to eq(16) + end + + it 'magic should be 0x5050' do + magic = @bytes_arr.shift(2).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT16) + expect(magic).to eq(0x5050) + expect(@header.magic).to eq(0x5050) + end + + it 'version should be 1' do + expect(@bytes_arr.shift).to eq(1) + end + + # by default it is an operation message and RequestType is a TwoWayRequest + it 'message_type_flag should be 64' do + expect(@bytes_arr.shift).to eq(64) + end + + it 'message_size should be 16' do + message_size = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(message_size).to eq(16) + expect(@header.message_size).to eq(16) + end + + it 'opaque should be 12' do + opaque = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT32) + expect(opaque).to eq(12) + expect(@header.opaque).to eq(12) + end + + it 'opcode should be 0' do + expect(@bytes_arr.shift).to eq(Juno::IO::ProtocolHeader::OpCodes::Nop) + expect(@header.opcode).to eq(Juno::IO::ProtocolHeader::OpCodes::Nop) + end + + it 'flag should be 0' do + expect(@bytes_arr.shift).to eq(0) + expect(@header.flag).to eq(0) + end + + it 'shard_id should be 0' do + shard_id = @bytes_arr.shift(4).pack(Juno::IO::OffsetWidth.UINT8('*')).unpack1(Juno::IO::OffsetWidth.UINT16) + expect(shard_id).to eq(0) + expect(@header.shard_id).to eq(0) + end +end + +describe 'Juno::IO::ProtocolHeader buffer read' do + before do + @header = Juno::IO::ProtocolHeader.new + buff = StringIO.new("PP\x01@\x00\x00\x00\x10\x00\x00\x00\f\x00\x00\x00\x00") + @header.read(buff) + end + + it 'number of bytes should be 16' do + expect(@header.message_size).to eq(16) + end + + it 'magic should be 0x5050' do + expect(@header.magic).to eq(0x5050) + end + + it 'version should be 1' do + expect(@header.version).to eq(1) + end + + # by default it is an operation message and RequestType is a TwoWayRequest + it 'message_type_flag should be 64' do + expect(@header.message_type_flag.message_request_type).to eq(Juno::IO::ProtocolHeader::RequestTypes::TwoWayRequest) + expect(@header.message_type_flag.message_type).to eq(Juno::IO::ProtocolHeader::MessageTypes::OperationalMessage) + end + + it 'message_size should be 16' do + expect(@header.message_size).to eq(16) + end + + it 'opaque should be 12' do + expect(@header.opaque).to eq(12) + end + + it 'opcode should be 0' do + expect(@header.opcode).to eq(Juno::IO::ProtocolHeader::OpCodes::Nop) + end + + it 'flag should be 0' do + expect(@header.flag).to eq(Juno::IO::ProtocolHeader::OpCodes::Nop) + end + + it 'shard_id should be 0' do + expect(@header.shard_id).to eq(0) + end +end diff --git a/client/Ruby/juno/spec/spec_helper.rb b/client/Ruby/juno/spec/spec_helper.rb new file mode 100644 index 00000000..253df0f1 --- /dev/null +++ b/client/Ruby/juno/spec/spec_helper.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + config.shared_context_metadata_behavior = :apply_to_host_groups +end diff --git a/client/Ruby/sample.rb b/client/Ruby/sample.rb new file mode 100644 index 00000000..09e4125f --- /dev/null +++ b/client/Ruby/sample.rb @@ -0,0 +1,41 @@ +require 'juno' + +Juno.configure do |config| + config.file_path = URI.join('file:///', '') + config.log_file = '' + config.ssl_cert_file = '' + config.ssl_key_file = '' +end + +# Rails cache store +juno_client = Juno::Client::CacheStore.new +juno_client.write('key', 'value') + +# Synchronous Client +juno_client = Juno::Client::SyncClient.new +resp = juno_client.create('key', 'value') +resp = juno_client.get('key') +resp = juno_client.update('key', 'newvalue') + + +# Return Juno::Client::JunoResponse +resp = juno_client.create('15', '99') +resp = juno_client.get('15') +resp = juno_client.update('15', '100') + + +# Asyn Client +class Callback + def update(time, value, reason) + puts time + if reason.to_s.empty? + puts value + else + puts "failed: #{reason}" + end + end +end + +juno_client = Juno::Client::ReactClient.new +juno_client.create('mykey', 'myvalue') +juno_client.add_observer(Callback.new) diff --git a/cmd/clustermgr/clusterctl/clusterctl.go b/cmd/clustermgr/clusterctl/clusterctl.go index 24a3d289..7d2f17be 100644 --- a/cmd/clustermgr/clusterctl/clusterctl.go +++ b/cmd/clustermgr/clusterctl/clusterctl.go @@ -28,11 +28,11 @@ import ( "path/filepath" "strings" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/version" - "juno/cmd/clustermgr/cmd" + "github.com/paypal/junodb/cmd/clustermgr/cmd" ) // @@ -64,7 +64,7 @@ func main() { flag.StringVar(&flagScale, "scale", "", "n:n:n:n:n") flag.BoolVar(&flagVerbose, "verbose", false, "verbose -- print more info") - flag.StringVar(&flagCmd, "cmd", "", "command -- store, redist, redistserv") + flag.StringVar(&flagCmd, "cmd", "", "command -- store, redist, redistserv, zonemarkdown") flag.StringVar(&flagType, "type", "cluster_info", "type -- cluster_info, auto, abort") flag.IntVar(&flagZoneid, "zone", -1, "specify zone id") @@ -173,5 +173,5 @@ func printUsage() { fmt.Printf("\nAbort redist: ./%s --cmd redist --type abort\n", progName) fmt.Printf("redist resume: ./%s --cmd redist --type resume --zone [n] --ratelimit 10000 (optional, in kb)\n", progName) - fmt.Printf("Zone markdown: ./%s --cmd markdown --type set/get/delete --zone [n] (--zone -1 disables markdwon)\n", progName) + fmt.Printf("Zone markdown: ./%s --cmd zonemarkdown --type set/get/delete --zone [n] (--zone -1 disables markdwon)\n", progName) } diff --git a/cmd/clustermgr/clustermgr.go b/cmd/clustermgr/clustermgr.go index 4bc94f1f..6ccba001 100644 --- a/cmd/clustermgr/clustermgr.go +++ b/cmd/clustermgr/clustermgr.go @@ -27,11 +27,11 @@ import ( "os" "path/filepath" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/version" - "juno/cmd/clustermgr/cmd" + "github.com/paypal/junodb/cmd/clustermgr/cmd" ) var ( @@ -59,7 +59,7 @@ func main() { flag.StringVar(&flagConfigNew, "new_config", "", "new configfile") flag.BoolVar(&flagDryrun, "dryrun", false, "dry run -- do not save to etcd") flag.BoolVar(&flagVerbose, "verbose", false, "verbose -- print more info") - flag.StringVar(&flagCmd, "cmd", "", "command -- store, redist") + flag.StringVar(&flagCmd, "cmd", "", "command -- store, redist, redistserv, zonemarkdown") flag.StringVar(&flagType, "type", "cluster_info", "type -- cluster_info, auto, abort") flag.IntVar(&flagZoneid, "zone", -1, "specify zone id") flag.IntVar(&flagSkipZone, "skipzone", -1, "specify zone id to skip") @@ -180,5 +180,5 @@ func printUsage() { fmt.Printf("Dump redist start_src to stdout: ./%s --new_config redist.toml --cmd redist --type start_src --zone [n] --dryrun --automarkdown=false\n", progName) fmt.Printf("Dump redist commit to stdout: ./%s --new_config redist.toml --cmd redist --type commit --dryrun\n", progName) fmt.Printf("Dump redist resume: ./%s --new_config redist.toml --cmd redist --type resume --zone [n] --ratelimit 10000 (optional, in kb)\n", progName) - fmt.Printf("Zone markdown: ./%s --config config.toml --cmd markdown --type set/get/delete --zone [n] (--zone -1 disables markdwon)\n", progName) + fmt.Printf("Zone markdown: ./%s --config config.toml --cmd zonemarkdown --type set/get/delete --zone [n] (--zone -1 disables markdwon)\n", progName) } diff --git a/cmd/clustermgr/cmd/cmd.go b/cmd/clustermgr/cmd/cmd.go index f9fce42f..f684f9fa 100644 --- a/cmd/clustermgr/cmd/cmd.go +++ b/cmd/clustermgr/cmd/cmd.go @@ -27,10 +27,10 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cluster" - "juno/pkg/etcd" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" ) func GetStatus(configFile string) { diff --git a/cmd/clustermgr/cmd/config.go b/cmd/clustermgr/cmd/config.go index 8d67d49a..4089b994 100644 --- a/cmd/clustermgr/cmd/config.go +++ b/cmd/clustermgr/cmd/config.go @@ -26,10 +26,10 @@ import ( "github.com/BurntSushi/toml" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cluster" - "juno/pkg/etcd" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" ) var ( diff --git a/cmd/dbscanserv/app/cmd.go b/cmd/dbscanserv/app/cmd.go index a642a978..59b3beeb 100644 --- a/cmd/dbscanserv/app/cmd.go +++ b/cmd/dbscanserv/app/cmd.go @@ -28,12 +28,12 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/dbscanserv/prime" - "juno/cmd/storageserv/compact" - "juno/cmd/storageserv/storage/db" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/cmd/storageserv/compact" + "github.com/paypal/junodb/cmd/storageserv/storage/db" ) type CmdLine struct { diff --git a/cmd/dbscanserv/app/collect.go b/cmd/dbscanserv/app/collect.go index 5d8a49d9..7cd2f358 100644 --- a/cmd/dbscanserv/app/collect.go +++ b/cmd/dbscanserv/app/collect.go @@ -25,10 +25,10 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/dbscanserv/prime" - "juno/pkg/logging" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/pkg/logging" ) type Collector struct { diff --git a/cmd/dbscanserv/app/init.go b/cmd/dbscanserv/app/init.go index d81a98c8..1feb7864 100644 --- a/cmd/dbscanserv/app/init.go +++ b/cmd/dbscanserv/app/init.go @@ -27,15 +27,15 @@ import ( "github.com/BurntSushi/toml" - "juno/third_party/forked/golang/glog" - - "juno/cmd/clustermgr/cmd" - "juno/cmd/dbscanserv/config" - "juno/cmd/dbscanserv/prime" - "juno/cmd/storageserv/storage/db" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/sec" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/clustermgr/cmd" + "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/sec" ) type CmdConfig cmd.Config diff --git a/cmd/dbscanserv/app/patch.go b/cmd/dbscanserv/app/patch.go index 70bf2e93..d1f8acbe 100644 --- a/cmd/dbscanserv/app/patch.go +++ b/cmd/dbscanserv/app/patch.go @@ -27,14 +27,14 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" - - "juno/cmd/dbscanserv/config" - "juno/cmd/dbscanserv/prime" - "juno/cmd/storageserv/storage/db" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" + + "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type CmdUpdatePatch struct { diff --git a/cmd/dbscanserv/app/remote.go b/cmd/dbscanserv/app/remote.go index 46d4ca4d..b6aa6f8f 100644 --- a/cmd/dbscanserv/app/remote.go +++ b/cmd/dbscanserv/app/remote.go @@ -30,11 +30,11 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/dbscanserv/config" - "juno/cmd/dbscanserv/prime" - "juno/pkg/net/netutil" + "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/pkg/net/netutil" ) type Remote int diff --git a/cmd/dbscanserv/app/rpcclient.go b/cmd/dbscanserv/app/rpcclient.go index e468557e..b02449fd 100644 --- a/cmd/dbscanserv/app/rpcclient.go +++ b/cmd/dbscanserv/app/rpcclient.go @@ -27,10 +27,10 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/dbscanserv/config" - "juno/cmd/dbscanserv/prime" + "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/dbscanserv/prime" ) type RpcClient struct { diff --git a/cmd/dbscanserv/app/scan.go b/cmd/dbscanserv/app/scan.go index 331a63d4..0321514f 100644 --- a/cmd/dbscanserv/app/scan.go +++ b/cmd/dbscanserv/app/scan.go @@ -24,11 +24,11 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/dbscanserv/prime" - "juno/cmd/storageserv/storage/db" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/cmd/storageserv/storage/db" ) // Map from zoneid, shardid to Scanner diff --git a/cmd/dbscanserv/junoctl/junoctl.go b/cmd/dbscanserv/junoctl/junoctl.go index c03045c3..2d6894fe 100644 --- a/cmd/dbscanserv/junoctl/junoctl.go +++ b/cmd/dbscanserv/junoctl/junoctl.go @@ -25,9 +25,9 @@ import ( "os" "path/filepath" - "juno/cmd/dbscanserv/app" - "juno/pkg/version" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/cmd/dbscanserv/app" + "github.com/paypal/junodb/pkg/version" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func main() { diff --git a/cmd/dbscanserv/main.go b/cmd/dbscanserv/main.go index de9fe60a..1a8461ff 100644 --- a/cmd/dbscanserv/main.go +++ b/cmd/dbscanserv/main.go @@ -27,11 +27,11 @@ import ( "strconv" "strings" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/dbscanserv/app" - "juno/cmd/dbscanserv/prime" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/dbscanserv/app" + "github.com/paypal/junodb/cmd/dbscanserv/prime" + "github.com/paypal/junodb/pkg/version" ) func parseKeyRange(keyRange string, cmd string) (start int, stop int, skip int) { diff --git a/cmd/dbscanserv/patch/relay.go b/cmd/dbscanserv/patch/relay.go index a3014f34..8c73a2ab 100644 --- a/cmd/dbscanserv/patch/relay.go +++ b/cmd/dbscanserv/patch/relay.go @@ -22,12 +22,12 @@ package patch import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/dbscanserv/app" - "juno/cmd/dbscanserv/config" - "juno/cmd/storageserv/storage/db" - "juno/pkg/proto" + "github.com/paypal/junodb/cmd/dbscanserv/app" + "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/proto" ) // Called by storageserv. diff --git a/cmd/dbscanserv/prime/db.go b/cmd/dbscanserv/prime/db.go index 5e240a5f..42719e01 100644 --- a/cmd/dbscanserv/prime/db.go +++ b/cmd/dbscanserv/prime/db.go @@ -26,10 +26,10 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/storageserv/storage/db" + "github.com/paypal/junodb/cmd/storageserv/storage/db" ) // Map from zoneid, nodeid to db handle diff --git a/cmd/dbscanserv/prime/log.go b/cmd/dbscanserv/prime/log.go index 6cf9312c..efb1de63 100644 --- a/cmd/dbscanserv/prime/log.go +++ b/cmd/dbscanserv/prime/log.go @@ -23,7 +23,7 @@ import ( "fmt" "os" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/cmd/dbscanserv/prime/meta.go b/cmd/dbscanserv/prime/meta.go index b1036384..61d752b8 100644 --- a/cmd/dbscanserv/prime/meta.go +++ b/cmd/dbscanserv/prime/meta.go @@ -28,9 +28,9 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/storage/db" + "github.com/paypal/junodb/cmd/storageserv/storage/db" ) type Meta struct { diff --git a/cmd/dbscanserv/prime/opdata.go b/cmd/dbscanserv/prime/opdata.go index 58e198b8..20176e6e 100644 --- a/cmd/dbscanserv/prime/opdata.go +++ b/cmd/dbscanserv/prime/opdata.go @@ -26,10 +26,10 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/storage/db" - "juno/pkg/proto" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/proto" ) type OpRecord struct { diff --git a/cmd/dbscanserv/prime/replicate.go b/cmd/dbscanserv/prime/replicate.go index abde2776..2a4d392c 100644 --- a/cmd/dbscanserv/prime/replicate.go +++ b/cmd/dbscanserv/prime/replicate.go @@ -24,12 +24,12 @@ import ( "runtime" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/internal/cli" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/sec" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/sec" ) var ( diff --git a/cmd/dbscanserv/prime/result.go b/cmd/dbscanserv/prime/result.go index d68b9251..9e589903 100644 --- a/cmd/dbscanserv/prime/result.go +++ b/cmd/dbscanserv/prime/result.go @@ -23,10 +23,10 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/util" ) type KeyList struct { diff --git a/cmd/etcdsvr/etcdsvr.py b/cmd/etcdsvr/etcdsvr.py index 31b46b1d..b4b6dc49 100755 --- a/cmd/etcdsvr/etcdsvr.py +++ b/cmd/etcdsvr/etcdsvr.py @@ -24,6 +24,7 @@ import logging import os import random +import shlex import signal import socket import subprocess @@ -62,13 +63,27 @@ def ip_in_use(ip, port): s.close() return True - except socket.error as e: + except socket.error: pass - except Exception as e: + except Exception: pass return False - + +def run_cmd(cmd, get_result=False): + result = "" + try: + out = None + if get_result: + out = subprocess.PIPE + re = subprocess.run(shlex.split(cmd), stdout=out, stderr=out, + universal_newlines=True, check=True) + result = str(re.stdout) + + except subprocess.CalledProcessError: + pass + return result + class Config(): # Init default. def __init__(self): @@ -95,8 +110,8 @@ def get_members(self): cmd_list = "%s member list" % (etcd_cmd) members = "" try: - members = subprocess.check_output(cmd_list, shell=False) - except subprocess.CalledProcessError as e: + members = run_cmd(cmd_list, get_result=True) + except subprocess.CalledProcessError: pass return members @@ -105,25 +120,23 @@ def display_status(self): os.environ["ETCDCTL_API"] = "3" etcd_cmd = '%s/etcdctl --endpoints="%s"' % (os.getcwd(), self.cluster_endpoints) - cmd_list = "%s member list 2>&1 | cat" % (etcd_cmd) - cmd_status = "%s endpoint status 2>&1 | cat" % (etcd_cmd) - cmd_health = "%s endpoint health 2>&1 | cat" % (etcd_cmd) - - out = etcd_cmd - out += "\n\n===== member list\n" + subprocess.check_output(cmd_list, shell=False) - print(out) - out = "===== endpoint status\n" + subprocess.check_output(cmd_status, shell=False) - print(out) - out = "===== endpoint health\n" + subprocess.check_output(cmd_health, shell=False) - print(out) + cmd_list = "%s member list" % (etcd_cmd) + cmd_status = "%s endpoint status" % (etcd_cmd) + cmd_health = "%s endpoint health" % (etcd_cmd) + + print(etcd_cmd + "\n\n===== member list\n") + run_cmd(cmd_list) + + print("\n===== endpoint status\n") + run_cmd(cmd_status) + + print("\n===== endpoint health\n") + run_cmd(cmd_health) # Join an existing cluster. def join_cluster(self): etcd_cmd = '%s/etcdctl --endpoints="%s"' % (os.getcwd(), self.cluster_endpoints) - cmd_select = "%s member list | grep ', %s, http' | awk -F',' '{print $1}'" % ( - etcd_cmd, self.etcd_name - ) cmd_add = "%s member add %s --peer-urls=%s" % ( etcd_cmd, self.etcd_name, self.peer_url @@ -133,41 +146,48 @@ def join_cluster(self): ok = True err = None - resp = ">> Members:\n" try: os.environ["ETCDCTL_API"] = "3" - resp += self.get_members() + text = self.get_members() hexid = "" - + resp = ">> Members:\n" + text + print(resp) + # Remove the current entry if any - resp += "\n>> Select:\n%s\n\n" % (cmd_select) - hexid = subprocess.check_output(cmd_select, shell=False) + lines = text.split("\n") + for li in lines: + tokens = li.split(", ") + if len(tokens) > 3 and self.etcd_name == tokens[2]: + hexid = tokens[0] + break if len(hexid) > 0: - cmd_remove = "%s member remove %s" % (etcd_cmd, hexid) - resp += "\n>> Remove:\n%s\n\n" % (cmd_remove) - - resp += subprocess.check_output(cmd_remove, stderr=subprocess.STDOUT, shell=False) + cmd_remove = "%s member remove %s\n\n" % (etcd_cmd, hexid) + print("\n>> Remove:\n%s" % (cmd_remove)) + resp += cmd_remove + + run_cmd(cmd_remove) sleep(5) # Add a new entry - resp += "\n>> Add:\n%s\n\n" % (cmd_add) - - resp += subprocess.check_output(cmd_add, stderr=subprocess.STDOUT, shell=False) - - resp += "\n>> Members:\n" - resp += self.get_members() - resp += "\n" - - resp += cmd_rm - resp += "\n" + msg = "\n>> Add:\n%s\n\n" % (cmd_add) + print(msg) + resp += msg + + run_cmd(cmd_add) + msg = "\n>> Members:\n" + self.get_members() + print(msg) + resp += msg + + msg = "\n" + cmd_rm + "\n" + print(msg) + resp += msg except subprocess.CalledProcessError as e: err = e.output ok = False - print(resp) with open("join.log", "w+") as f: f.write(resp) @@ -189,7 +209,6 @@ def add_json_cfg(self): h["advertise-client-urls"] = client_url h["initial-advertise-peer-urls"] = self.peer_url - dir = self.etcd_name + ".etcd" if self.is_existing_cluster: # Join an existing cluster h["initial-cluster-state"] = "existing" @@ -339,23 +358,22 @@ def sig_handler(self, sig, frame): def is_endpoint_healthy(self, wait_time): os.environ["ETCDCTL_API"] = "3" etcd_cmd = '%s/etcdctl --endpoints="%s"' % (os.getcwd(), self.local_endpoint) - cmd_health = "%s endpoint health 2>&1 | cat" % (etcd_cmd) + cmd_health = "%s endpoint health" % (etcd_cmd) result = "" now = int(time()) - for i in range(50): - sleep(2) + for i in range(10): + sleep(5) t = int(time()) - now if t > wait_time: break - if t > 60: - msg = "unhealthy_%s" % (self.etcd_name) + if t > 50: + msg = "unhealthy_%s retry ..." % (self.etcd_name) self.logger.error("[MANAGER] %s" % (msg)) - result = subprocess.check_output(cmd_health, shell=False) - health_check_bytes = str.encode("is healthy") - if health_check_bytes in result: + result = run_cmd(cmd_health, get_result=True) + if "is health" in result: return True self.logger.info("[MANAGER] %s" % (result)) @@ -418,8 +436,8 @@ def watch_and_recycle(self, cfg): print(" ") self.logger.info("[MANAGER] Started etcd process %d" % (self.pid)) - wait_time = 85 + random.randint(0,10) - while False: + wait_time = 60 + random.randint(0,10) + while False: #not self.is_endpoint_healthy(wait_time): if restartCount > 0: self.shutdown_server() @@ -436,6 +454,8 @@ def watch_and_recycle(self, cfg): self.shutdown(-1) # exit print("Starting etcd process %d succeeded." % (self.pid)) + if os.path.exists("join.log"): + os.remove("join.log") self.server.wait() # etcd server has exited. @@ -469,7 +489,7 @@ def watch_and_recycle(self, cfg): with open("./etcdsvr.pid", "w") as f: f.write("%d\n" % (os.getpid())) - + cfg = Config() err = cfg.parse_cfg(False) if err: diff --git a/cmd/etcdsvr/tool.py b/cmd/etcdsvr/tool.py index 65b10dbe..8a26f4cb 100755 --- a/cmd/etcdsvr/tool.py +++ b/cmd/etcdsvr/tool.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # # Copyright 2023 PayPal Inc. # diff --git a/cmd/proxy/app/proxy.go b/cmd/proxy/app/proxy.go index bfc55518..6855cf23 100644 --- a/cmd/proxy/app/proxy.go +++ b/cmd/proxy/app/proxy.go @@ -30,13 +30,13 @@ import ( "os/exec" "path/filepath" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/config" - "juno/pkg/cmd" - "juno/pkg/initmgr" - "juno/pkg/sec" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/version" ) func Main() { diff --git a/cmd/proxy/app/proxymgr.go b/cmd/proxy/app/proxymgr.go index 19cc1433..f1692190 100644 --- a/cmd/proxy/app/proxymgr.go +++ b/cmd/proxy/app/proxymgr.go @@ -28,17 +28,17 @@ import ( "strings" "syscall" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats" - "juno/pkg/cmd" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/sec" - "juno/pkg/service" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/util" ) const ( diff --git a/cmd/proxy/app/proxymonwkr.go b/cmd/proxy/app/proxymonwkr.go index 28ed4e7e..73ef97e7 100644 --- a/cmd/proxy/app/proxymonwkr.go +++ b/cmd/proxy/app/proxymonwkr.go @@ -24,14 +24,14 @@ import ( "strings" "sync" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" ) type ( diff --git a/cmd/proxy/app/proxywkr.go b/cmd/proxy/app/proxywkr.go index 56107f29..b2f8d92b 100644 --- a/cmd/proxy/app/proxywkr.go +++ b/cmd/proxy/app/proxywkr.go @@ -28,24 +28,24 @@ import ( "strconv" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/handler" - "juno/cmd/proxy/replication" - "juno/cmd/proxy/stats" - "juno/cmd/proxy/stats/shmstats" - "juno/cmd/proxy/watcher" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/sec" - "juno/pkg/service" - "juno/pkg/udf" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/handler" + "github.com/paypal/junodb/cmd/proxy/replication" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/cmd/proxy/watcher" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/udf" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/cmd/proxy/config/config.go b/cmd/proxy/config/config.go index 8c399ad6..b00c5994 100644 --- a/cmd/proxy/config/config.go +++ b/cmd/proxy/config/config.go @@ -26,21 +26,21 @@ import ( "path/filepath" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - repconfig "juno/cmd/proxy/replication/config" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/initmgr" - "juno/pkg/io" - cal "juno/pkg/logging/cal/config" - otel "juno/pkg/logging/otel/config" - "juno/pkg/sec" - "juno/pkg/service" - "juno/pkg/util" - "juno/pkg/version" + repconfig "github.com/paypal/junodb/cmd/proxy/replication/config" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/io" + cal "github.com/paypal/junodb/pkg/logging/cal/config" + otel "github.com/paypal/junodb/pkg/logging/otel/config" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/pkg/version" ) var ( @@ -211,7 +211,7 @@ func (c *Config) IsEncryptionEnabled() bool { return c.ReplicationEncryptionEnabled || c.PayloadEncryptionEnabled } -///TODO find a better name +// /TODO find a better name func (c *Config) GetSecFlag() (f sec.Flag) { if c.IsTLSEnabled(true) { f |= sec.KFlagServerTlsEnabled diff --git a/cmd/proxy/config/limitscfg.go b/cmd/proxy/config/limitscfg.go index 9d475c02..51d23fdd 100644 --- a/cmd/proxy/config/limitscfg.go +++ b/cmd/proxy/config/limitscfg.go @@ -24,9 +24,9 @@ import ( "math" "sync" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cfg" + "github.com/paypal/junodb/pkg/cfg" ) var ( diff --git a/cmd/proxy/handler/requestHandler.go b/cmd/proxy/handler/requestHandler.go index 6d55adad..85d67abc 100644 --- a/cmd/proxy/handler/requestHandler.go +++ b/cmd/proxy/handler/requestHandler.go @@ -22,15 +22,15 @@ package handler import ( "os" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/proc" - "juno/cmd/proxy/stats" - "juno/pkg/io" - "juno/pkg/net/netutil" - "juno/pkg/proto" - "juno/pkg/service" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/proc" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/net/netutil" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/service" ) var _ io.IRequestHandler = (*RequestHandler)(nil) diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go index 5e18bcd4..540b7e91 100644 --- a/cmd/proxy/main.go +++ b/cmd/proxy/main.go @@ -19,7 +19,7 @@ package main -import "juno/cmd/proxy/app" +import "github.com/paypal/junodb/cmd/proxy/app" func main() { app.Main() diff --git a/cmd/proxy/proc/base.go b/cmd/proxy/proc/base.go index 76d6197f..48b65f89 100644 --- a/cmd/proxy/proc/base.go +++ b/cmd/proxy/proc/base.go @@ -28,22 +28,22 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/replication" - proxystats "juno/cmd/proxy/stats" - "juno/pkg/cluster" - "juno/pkg/debug" - "juno/pkg/errors" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" - "juno/pkg/shard" - "juno/pkg/stats" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/replication" + proxystats "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/errors" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/util" ) const ( @@ -173,9 +173,9 @@ func (r *ProxyInResponseContext) OnComplete() { } logging.LogToCal(opcode, r.GetOpStatus(), rht, calData) } - if otel.IsEnabled() { - otel.RecordOperation(r.stats.Opcode.String(), r.stats.ResponseStatus.ShortNameString(), int64(rhtus)) - } + + otel.RecordOperation(r.stats.Opcode.String(), r.stats.ResponseStatus, int64(rhtus)) + r.stats.OnComplete(uint32(rhtus), r.GetOpStatus()) proxystats.SendProcState(r.stats) @@ -339,9 +339,7 @@ func (p *ProcessorBase) replyToClient(resp *ResponseWrapper) { if cal.IsEnabled() { calLogReqProcError(kDecrypt, []byte(errmsg)) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kDecrypt}, {otel.Status, otel.StatusError}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kDecrypt}, {otel.Status, otel.StatusError}}) msg := p.clientRequest.CreateResponse() msg.SetOpStatus(proto.OpStatusInternal) var raw proto.RawMessage @@ -571,9 +569,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("len"), szKey) calLogReqProcEvent(kBadParamInvalidKeyLen, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) return false } szNs := len(r.GetNamespace()) @@ -584,9 +580,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("len"), szNs) calLogReqProcEvent(kBadParamInvalidNsLen, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidNsLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidNsLen}}) return false } ttl := r.GetTimeToLive() @@ -597,9 +591,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("ttl"), int(ttl)) calLogReqProcEvent(kBadParamInvalidTTL, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) return false } } else { @@ -610,9 +602,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddInt([]byte("len"), szKey) calLogReqProcEvent(kBadParamInvalidKeyLen, data.Bytes()) glog.Warningf("limit exceeded: key length %d > %d", szKey, limits.MaxKeyLength) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) return false } if limits.MaxTimeToLive != 0 && ttl > limits.MaxTimeToLive { @@ -621,9 +611,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddInt([]byte("ttl"), int(ttl)) calLogReqProcEvent(kBadParamInvalidTTL, data.Bytes()) glog.Warningf("limit exceeded: TTL %d > %d", ttl, limits.MaxTimeToLive) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) return false } szValue := r.GetPayloadValueLength() @@ -633,9 +621,7 @@ func (p *ProcessorBase) validateInboundRequest(r *proto.OperationalMessage) bool data.AddInt([]byte("len"), int(szValue)) calLogReqProcEvent(kBadParamInvalidValueLen, data.Bytes()) glog.Warningf("limit exceeded: payload length %d > %d", szValue, limits.MaxPayloadLength) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidValueLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidValueLen}}) return false } } @@ -692,11 +678,11 @@ func (p *ProcessorBase) Process(request io.IRequestContext) bool { } } } - if otel.IsEnabled() { - if p.clientRequest.IsForReplication() { - otel.RecordCount(otel.RAPI, nil) - } + + if p.clientRequest.IsForReplication() { + otel.RecordCount(otel.RAPI, nil) } + p.shardId = shardId.Uint16() if err := proto.SetShardId(p.requestContext.GetMessage(), p.shardId); err != nil { @@ -770,9 +756,7 @@ func (p *ProcessorBase) OnRequestTimeout() { b.AddOpCode(p.clientRequest.GetOpCode()).AddReqIdString(p.requestID) calLogReqProcEvent(kReqTimeout, b.Bytes()) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kReqTimeout}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kReqTimeout}}) p.replyStatusToClient(proto.OpStatusBusy) } now := time.Now() @@ -794,9 +778,7 @@ func (p *ProcessorBase) OnCancelled() { b.AddOpCode(p.clientRequest.GetOpCode()).AddReqIdString(p.requestID) calLogReqProcEvent(kReqCancelled, b.Bytes()) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kReqCancelled}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kReqCancelled}}) p.replyStatusToClient(proto.OpStatusBusy) } now := time.Now() @@ -841,10 +823,8 @@ func (p *ProcessorBase) handleSSTimeout(now time.Time) { writeBasicSSRequestInfo(b, st.opCode, int(st.ssIndex), p.ssGroup.processors[st.ssIndex].GetConnInfo(), p) calLogReqProcEvent(calNameReqTimeoutFor(st.opCode), b.Bytes()) } - if otel.IsEnabled() { - status := otel.SSReqTimeout + "_" + st.opCode.String() - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, status}}) - } + status := otel.SSReqTimeout + "_" + st.opCode.String() + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, status}}) if cluster.GetShardMgr().StatsEnabled() { zoneId, hostId := p.ssGroup.processors[st.ssIndex].GetNodeInfo() cluster.GetShardMgr().SendStats(zoneId, hostId, true, confSSRequestTimeout.Microseconds()) @@ -918,10 +898,8 @@ func (p *ProcessorBase) preprocessAndValidateResponse(resp io.IResponseContext) errStr := strings.Replace(statusText, " ", "_", -1) calLogReqProcEvent(fmt.Sprintf("SS_%s", errStr), buf.Bytes()) //TODO revisit log as error? } - if otel.IsEnabled() { - errStr := strings.Replace(statusText, " ", "_", -1) - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, fmt.Sprintf("SS_%s", errStr)}}) - } + errStr := strings.Replace(statusText, " ", "_", -1) + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, fmt.Sprintf("SS_%s", errStr)}}) st.state = stSSResponseIOError st.timeRespReceived = time.Now() p.self.OnSSIOError(st) diff --git a/cmd/proxy/proc/create.go b/cmd/proxy/proc/create.go index e73e3895..04904990 100644 --- a/cmd/proxy/proc/create.go +++ b/cmd/proxy/proc/create.go @@ -23,11 +23,11 @@ import ( "fmt" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" ) var _ ITwoPhaseProcessor = (*CreateProcessor)(nil) @@ -82,9 +82,7 @@ func (p *CreateProcessor) setInitSSRequest() bool { if cal.IsEnabled() { calLogReqProcError(kEncrypt, []byte(errmsg)) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kEncrypt}, {otel.Status, otel.StatusError}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kEncrypt}, {otel.Status, otel.StatusError}}) p.replyStatusToClient(proto.OpStatusInternal) return false } diff --git a/cmd/proxy/proc/destroy.go b/cmd/proxy/proc/destroy.go index e5c17c57..2c2fe5dc 100644 --- a/cmd/proxy/proc/destroy.go +++ b/cmd/proxy/proc/destroy.go @@ -20,7 +20,7 @@ package proc import ( - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) var _ IOnePhaseProcessor = (*DestroyProcessor)(nil) diff --git a/cmd/proxy/proc/destroy2.go b/cmd/proxy/proc/destroy2.go index 2cd78632..82ab5129 100644 --- a/cmd/proxy/proc/destroy2.go +++ b/cmd/proxy/proc/destroy2.go @@ -20,9 +20,9 @@ package proc import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) // SUCCESS: NoError, AlreadyFulfilled, NoKey diff --git a/cmd/proxy/proc/get.go b/cmd/proxy/proc/get.go index 5cfdf4ba..561c6ec8 100644 --- a/cmd/proxy/proc/get.go +++ b/cmd/proxy/proc/get.go @@ -20,10 +20,10 @@ package proc import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" ) // SUCCESS: NoError, NoKey, MarkedDelete diff --git a/cmd/proxy/proc/inbreqctx.go b/cmd/proxy/proc/inbreqctx.go index 7e96b1ed..f4b614c1 100644 --- a/cmd/proxy/proc/inbreqctx.go +++ b/cmd/proxy/proc/inbreqctx.go @@ -24,15 +24,15 @@ import ( goio "io" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/cmd/proxy/replication" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/replication" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" ) type IInbRequestContext interface { @@ -47,7 +47,7 @@ type IInbRequestContext interface { ReplyStatus(st proto.OpStatus) } -//InboundRequestContext Proxy Inbound request context +// InboundRequestContext Proxy Inbound request context type InboundRequestContext struct { io.InboundRequestContext proto.OperationalMessage @@ -75,9 +75,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("len"), szKey) calLogReqProcEvent(kBadParamInvalidKeyLen, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) return false } szNs := len(r.GetNamespace()) @@ -88,9 +86,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("len"), szNs) calLogReqProcEvent(kBadParamInvalidNsLen, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidNsLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidNsLen}}) return false } ttl := r.GetTimeToLive() @@ -101,9 +97,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddReqIdString(r.GetRequestIDString()) data.AddInt([]byte("ttl"), int(ttl)) calLogReqProcEvent(kBadParamInvalidTTL, data.Bytes()) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) return false } } else { @@ -114,9 +108,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddInt([]byte("len"), szKey) calLogReqProcEvent(kBadParamInvalidKeyLen, data.Bytes()) glog.Warningf("limit exceeded: key length %d > %d", szKey, limits.MaxKeyLength) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidKeyLen}}) return false } if limits.MaxTimeToLive != 0 && ttl > limits.MaxTimeToLive { @@ -125,9 +117,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddInt([]byte("ttl"), int(ttl)) calLogReqProcEvent(kBadParamInvalidTTL, data.Bytes()) glog.Warningf("limit exceeded: TTL %d > %d", ttl, limits.MaxTimeToLive) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidTTL}}) return false } szValue := r.GetPayloadValueLength() @@ -137,9 +127,7 @@ func (r *InboundRequestContext) ValidateRequest() bool { data.AddInt([]byte("len"), int(szValue)) calLogReqProcEvent(kBadParamInvalidValueLen, data.Bytes()) glog.Warningf("limit exceeded: payload length %d > %d", ttl, limits.MaxTimeToLive) - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidValueLen}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kBadParamInvalidValueLen}}) return false } } diff --git a/cmd/proxy/proc/pconfig.go b/cmd/proxy/proc/pconfig.go index 93beff00..c9a2c269 100644 --- a/cmd/proxy/proc/pconfig.go +++ b/cmd/proxy/proc/pconfig.go @@ -22,12 +22,12 @@ package proc import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/config" - "juno/pkg/cfg" - "juno/pkg/io" - "juno/pkg/proto" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/cfg" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" ) var ( diff --git a/cmd/proxy/proc/proc_logging.go b/cmd/proxy/proc/proc_logging.go index b1eab84a..b332433a 100644 --- a/cmd/proxy/proc/proc_logging.go +++ b/cmd/proxy/proc/proc_logging.go @@ -20,11 +20,11 @@ package proc import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) var ( diff --git a/cmd/proxy/proc/processor.go b/cmd/proxy/proc/processor.go index 18b1599b..ba29072c 100644 --- a/cmd/proxy/proc/processor.go +++ b/cmd/proxy/proc/processor.go @@ -22,12 +22,12 @@ package proc import ( "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" ) type IOnePhaseProcessor interface { @@ -135,9 +135,7 @@ func (p *TwoPhaseProcessor) setInitSSRequest() bool { if cal.IsEnabled() { calLogReqProcError(kEncrypt, []byte(errmsg)) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kEncrypt}, {otel.Status, otel.StatusError}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Operation, kEncrypt}, {otel.Status, otel.StatusError}}) p.replyStatusToClient(proto.OpStatusInternal) return false } @@ -351,9 +349,7 @@ func (p *TwoPhaseProcessor) onRepairFailure(rc *SSRequestContext) { writeBasicSSRequestInfo(buf, rc.opCode, int(rc.ssIndex), p.ssGroup.processors[rc.ssIndex].GetConnInfo(), &p.ProcessorBase) calLogReqProcEvent(kInconsistent, buf.Bytes()) } - if otel.IsEnabled() { - otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kInconsistent}}) - } + otel.RecordCount(otel.ReqProc, []otel.Tags{{otel.Status, kInconsistent}}) p.replyStatusToClient(proto.OpStatusInconsistent) } } diff --git a/cmd/proxy/proc/reqProcessorPool.go b/cmd/proxy/proc/reqProcessorPool.go index b62ffec3..6e7b1238 100644 --- a/cmd/proxy/proc/reqProcessorPool.go +++ b/cmd/proxy/proc/reqProcessorPool.go @@ -20,9 +20,9 @@ package proc import ( - "juno/cmd/proxy/stats" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type ReqProcessorPool struct { diff --git a/cmd/proxy/proc/set.go b/cmd/proxy/proc/set.go index c3c5fb8d..7f8e3e85 100644 --- a/cmd/proxy/proc/set.go +++ b/cmd/proxy/proc/set.go @@ -22,10 +22,10 @@ package proc import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) var _ ITwoPhaseProcessor = (*SetProcessor)(nil) diff --git a/cmd/proxy/proc/state.go b/cmd/proxy/proc/state.go index 62547cc7..ac8588ea 100644 --- a/cmd/proxy/proc/state.go +++ b/cmd/proxy/proc/state.go @@ -20,11 +20,11 @@ package proc import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/debug" - "juno/pkg/errors" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/errors" + "github.com/paypal/junodb/pkg/proto" ) type RequestAndStats struct { @@ -42,7 +42,7 @@ type RequestAndStats struct { funcIsSuccess func(proto.OpStatus) bool } -///TODO may just change to *SSRequestContext +// /TODO may just change to *SSRequestContext type ResponseWrapper struct { ssRequest *SSRequestContext } diff --git a/cmd/proxy/proc/udfget.go b/cmd/proxy/proc/udfget.go index 3d3c9108..91cfe219 100644 --- a/cmd/proxy/proc/udfget.go +++ b/cmd/proxy/proc/udfget.go @@ -20,9 +20,9 @@ package proc import ( - "juno/pkg/proto" - "juno/pkg/udf" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/udf" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var _ IOnePhaseProcessor = (*UDFGetProcessor)(nil) diff --git a/cmd/proxy/proc/update.go b/cmd/proxy/proc/update.go index c38503c4..9f3d6d15 100644 --- a/cmd/proxy/proc/update.go +++ b/cmd/proxy/proc/update.go @@ -22,11 +22,11 @@ package proc import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) var _ ITwoPhaseProcessor = (*UpdateProcessor)(nil) diff --git a/cmd/proxy/replication/config/repcfg.go b/cmd/proxy/replication/config/repcfg.go index 4278f208..93a00a74 100644 --- a/cmd/proxy/replication/config/repcfg.go +++ b/cmd/proxy/replication/config/repcfg.go @@ -24,8 +24,8 @@ import ( "strings" "time" - "juno/pkg/io" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/cmd/proxy/replication/pingreqctx.go b/cmd/proxy/replication/pingreqctx.go index 0d715d62..c7abf39f 100644 --- a/cmd/proxy/replication/pingreqctx.go +++ b/cmd/proxy/replication/pingreqctx.go @@ -24,12 +24,12 @@ import ( goio "io" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/cmd/proxy/replication/replicaterequest.go b/cmd/proxy/replication/replicaterequest.go index 5ce53dc8..bfc05e82 100644 --- a/cmd/proxy/replication/replicaterequest.go +++ b/cmd/proxy/replication/replicaterequest.go @@ -24,15 +24,15 @@ import ( goio "io" "time" - "juno/third_party/forked/golang/glog" - - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) var ( @@ -146,9 +146,8 @@ func (r *RepRequestContext) complete(calstatus string, opStatus string, rht time cal.AtomicTransaction(targetType, opCode, calstatus, rht, r.calBuf.Bytes()) } } - if otel.IsEnabled() { - otel.RecordReplication(opCode, opStatus, target, rht.Milliseconds()) - } + + otel.RecordReplication(opCode, opStatus, target, rht.Microseconds()) r.this.OnComplete() } @@ -221,9 +220,7 @@ func (r *RepRequestContext) Reply(resp io.IResponseContext) { } r.calBuf.AddDropReason("MaxRetry") } - if otel.IsEnabled() { - otel.RecordCount(otel.RRDropMaxRetry, []otel.Tags{{"target", r.targetId}}) - } + otel.RecordCount(otel.RRDropMaxRetry, []otel.Tags{{"target", r.targetId}}) r.errCnt.Add(1) r.complete(cal.StatusError, opstatus.String(), rht, opCodeText, r.targetId) return @@ -245,9 +242,7 @@ func (r *RepRequestContext) Reply(resp io.IResponseContext) { } r.calBuf.AddDropReason("QueueFull") } - if otel.IsEnabled() { - otel.RecordCount(otel.RRDropQueueFull, []otel.Tags{{otel.Target, r.targetId}}) - } + otel.RecordCount(otel.RRDropQueueFull, []otel.Tags{{otel.Target, r.targetId}}) r.dropCnt.Add(1) r.complete(cal.StatusError, opstatus.String(), rht, opCodeText, r.targetId) } @@ -261,9 +256,7 @@ func (r *RepRequestContext) Reply(resp io.IResponseContext) { } r.calBuf.AddDropReason("RecExpired") } - if otel.IsEnabled() { - otel.RecordCount(otel.RRDropRecExpired, []otel.Tags{{otel.Target, r.targetId}}) - } + otel.RecordCount(otel.RRDropRecExpired, []otel.Tags{{otel.Target, r.targetId}}) r.complete(cal.StatusSuccess, opstatus.String(), rht, opCodeText, r.targetId) } } diff --git a/cmd/proxy/replication/replicator.go b/cmd/proxy/replication/replicator.go index 4abcd607..b0a36b80 100644 --- a/cmd/proxy/replication/replicator.go +++ b/cmd/proxy/replication/replicator.go @@ -28,16 +28,16 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" - - repconfig "juno/cmd/proxy/replication/config" - proxystats "juno/cmd/proxy/stats" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + repconfig "github.com/paypal/junodb/cmd/proxy/replication/config" + proxystats "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/cmd/proxy/stats/clsConTmpl.go b/cmd/proxy/stats/clsConTmpl.go index ad3fc5c0..a41efdaa 100644 --- a/cmd/proxy/stats/clsConTmpl.go +++ b/cmd/proxy/stats/clsConTmpl.go @@ -24,7 +24,7 @@ import ( "fmt" "html/template" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/version" ) var ( diff --git a/cmd/proxy/stats/htmlsect.go b/cmd/proxy/stats/htmlsect.go index d490aade..b9cfdc43 100644 --- a/cmd/proxy/stats/htmlsect.go +++ b/cmd/proxy/stats/htmlsect.go @@ -25,10 +25,10 @@ import ( "html/template" "time" - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/cluster" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/stats" ) type ( diff --git a/cmd/proxy/stats/httphandler.go b/cmd/proxy/stats/httphandler.go index 46637934..9db66df8 100644 --- a/cmd/proxy/stats/httphandler.go +++ b/cmd/proxy/stats/httphandler.go @@ -23,13 +23,13 @@ import ( "fmt" "net/http" - //"juno/third_party/forked/golang/glog" + //"github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats/qry" - "juno/pkg/stats" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats/qry" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/version" ) var ( diff --git a/cmd/proxy/stats/monhandler.go b/cmd/proxy/stats/monhandler.go index aac7d7a8..cbf728eb 100644 --- a/cmd/proxy/stats/monhandler.go +++ b/cmd/proxy/stats/monhandler.go @@ -31,12 +31,12 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/stats" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/version" ) var () diff --git a/cmd/proxy/stats/qry/infoquery.go b/cmd/proxy/stats/qry/infoquery.go index 0b6e6fc9..a3f363af 100644 --- a/cmd/proxy/stats/qry/infoquery.go +++ b/cmd/proxy/stats/qry/infoquery.go @@ -27,7 +27,7 @@ import ( "strconv" "strings" - "juno/pkg/cluster" + "github.com/paypal/junodb/pkg/cluster" ) var ( diff --git a/cmd/proxy/stats/shmstats/shmstats.go b/cmd/proxy/stats/shmstats/shmstats.go index 29b5878f..42969265 100644 --- a/cmd/proxy/stats/shmstats/shmstats.go +++ b/cmd/proxy/stats/shmstats/shmstats.go @@ -34,12 +34,12 @@ import ( "unsafe" // "github.com/BurntSushi/toml" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/config" - "juno/pkg/io" - "juno/pkg/stats" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/util" ) const ( @@ -98,7 +98,7 @@ type ( Type uint16 CapQueue uint16 Addr [256]byte - Name [12]byte + Name [256]byte } serverStatsManagerT struct { stats *ServerStats @@ -944,7 +944,7 @@ func GetListenerStats() (stats []ListenerStats) { return } -//TODO make sure shmStats has been initialized.... +// TODO make sure shmStats has been initialized.... func GetCurrentWorkerStatsManager() *workerStatsManagerT { return shmStats.current } diff --git a/cmd/proxy/stats/shmstatswr.go b/cmd/proxy/stats/shmstatswr.go index e8b2aba8..b2ab3d90 100644 --- a/cmd/proxy/stats/shmstatswr.go +++ b/cmd/proxy/stats/shmstatswr.go @@ -25,9 +25,9 @@ import ( "time" "unsafe" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/logging/cal" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/stats" ) var ( diff --git a/cmd/proxy/stats/statelog.go b/cmd/proxy/stats/statelog.go index bf604907..d8a86328 100644 --- a/cmd/proxy/stats/statelog.go +++ b/cmd/proxy/stats/statelog.go @@ -31,13 +31,13 @@ import ( "syscall" "time" - // "juno/third_party/forked/golang/glog" + // "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cluster" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/stats" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/util" ) // counters diff --git a/cmd/proxy/stats/statsinit.go b/cmd/proxy/stats/statsinit.go index c06d369a..55d6da3c 100644 --- a/cmd/proxy/stats/statsinit.go +++ b/cmd/proxy/stats/statsinit.go @@ -22,9 +22,9 @@ package stats import ( "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" ) const ( @@ -39,9 +39,9 @@ type ( ) /* - Arguments - arg 0: Type stats.Type - arg 1: WorkerId int, if Type == KTypeWorker +Arguments +arg 0: Type stats.Type +arg 1: WorkerId int, if Type == KTypeWorker */ func Initialize(args ...interface{}) (err error) { var ( diff --git a/cmd/proxy/stats/statslogger.go b/cmd/proxy/stats/statslogger.go index 80cd7d0f..bff0eba5 100644 --- a/cmd/proxy/stats/statslogger.go +++ b/cmd/proxy/stats/statslogger.go @@ -29,12 +29,12 @@ import ( "path/filepath" "time" - "juno/cmd/proxy/config" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/io" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/stats" ) var ( diff --git a/cmd/proxy/watcher/watcher.go b/cmd/proxy/watcher/watcher.go index 35befb7d..056b44c7 100644 --- a/cmd/proxy/watcher/watcher.go +++ b/cmd/proxy/watcher/watcher.go @@ -28,12 +28,12 @@ import ( clientv3 "go.etcd.io/etcd/client/v3" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/proc" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/proxy/proc" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/util" ) type Watcher struct { diff --git a/cmd/storageserv/app/ssmgr.go b/cmd/storageserv/app/ssmgr.go index 4ee27b01..2a1f4d18 100644 --- a/cmd/storageserv/app/ssmgr.go +++ b/cmd/storageserv/app/ssmgr.go @@ -26,14 +26,14 @@ import ( "net" "os" - "juno/third_party/forked/golang/glog" - - "juno/cmd/storageserv/config" - "juno/pkg/cmd" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/net/netutil" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/net/netutil" ) const ( @@ -97,7 +97,7 @@ func (c *Manager) Parse(args []string) (err error) { return } -///TODO refactoring +// /TODO refactoring func (c *Manager) Exec() { initmgr.Register(config.Initializer, c.optConfigFile) diff --git a/cmd/storageserv/app/ssmonwkr.go b/cmd/storageserv/app/ssmonwkr.go index dbe9ada7..6e2311f5 100644 --- a/cmd/storageserv/app/ssmonwkr.go +++ b/cmd/storageserv/app/ssmonwkr.go @@ -24,14 +24,14 @@ import ( "strings" "sync" - "juno/third_party/forked/golang/glog" - - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/stats" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/stats" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" ) type ( diff --git a/cmd/storageserv/app/sswkr.go b/cmd/storageserv/app/sswkr.go index 73c7474f..10aa38c2 100644 --- a/cmd/storageserv/app/sswkr.go +++ b/cmd/storageserv/app/sswkr.go @@ -26,24 +26,24 @@ import ( "os" "strconv" - "juno/third_party/forked/golang/glog" - - "juno/cmd/dbscanserv/patch" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/handler" - "juno/cmd/storageserv/redist" - "juno/cmd/storageserv/stats" - "juno/cmd/storageserv/storage" - - "juno/cmd/storageserv/compact" - "juno/cmd/storageserv/watcher" - "juno/pkg/cluster" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/service" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/dbscanserv/patch" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/handler" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/cmd/storageserv/stats" + "github.com/paypal/junodb/cmd/storageserv/storage" + + "github.com/paypal/junodb/cmd/storageserv/compact" + "github.com/paypal/junodb/cmd/storageserv/watcher" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/util" ) type Worker struct { diff --git a/cmd/storageserv/app/storagemgr.go b/cmd/storageserv/app/storagemgr.go index ee9c288d..20b88626 100644 --- a/cmd/storageserv/app/storagemgr.go +++ b/cmd/storageserv/app/storagemgr.go @@ -34,10 +34,10 @@ import ( "syscall" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/cmd/storageserv/app/storageserv.go b/cmd/storageserv/app/storageserv.go index 11d8ac57..f2d1b4bd 100644 --- a/cmd/storageserv/app/storageserv.go +++ b/cmd/storageserv/app/storageserv.go @@ -26,9 +26,9 @@ import ( "path/filepath" "strings" - "juno/pkg/cmd" - "juno/pkg/initmgr" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/version" ) func init() { @@ -96,7 +96,7 @@ func Main() { } -//TODO may customize this or remove inappalicable glob flags +// TODO may customize this or remove inappalicable glob flags func printUsage() { progName := filepath.Base(os.Args[0]) fmt.Printf(` diff --git a/cmd/storageserv/compact/dbclient.go b/cmd/storageserv/compact/dbclient.go index 6d92d985..4428530a 100644 --- a/cmd/storageserv/compact/dbclient.go +++ b/cmd/storageserv/compact/dbclient.go @@ -28,10 +28,10 @@ import ( "path/filepath" "time" - "juno/cmd/storageserv/storage/db" - "juno/pkg/service" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" ) type DbClient struct { diff --git a/cmd/storageserv/compact/filter.go b/cmd/storageserv/compact/filter.go index 226e4aa6..53d0cace 100644 --- a/cmd/storageserv/compact/filter.go +++ b/cmd/storageserv/compact/filter.go @@ -24,7 +24,7 @@ import ( "github.com/BurntSushi/toml" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type namespaceFilter struct { diff --git a/cmd/storageserv/config/config.go b/cmd/storageserv/config/config.go index 524a3de3..253d1f70 100644 --- a/cmd/storageserv/config/config.go +++ b/cmd/storageserv/config/config.go @@ -29,23 +29,23 @@ import ( "path/filepath" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - dbscan "juno/cmd/dbscanserv/config" - "juno/cmd/storageserv/redist" - "juno/cmd/storageserv/storage/db" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/initmgr" - "juno/pkg/io" - cal "juno/pkg/logging/cal/config" - otel "juno/pkg/logging/otel/config" - "juno/pkg/service" - "juno/pkg/shard" - "juno/pkg/util" - "juno/pkg/version" + dbscan "github.com/paypal/junodb/cmd/dbscanserv/config" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/io" + cal "github.com/paypal/junodb/pkg/logging/cal/config" + otel "github.com/paypal/junodb/pkg/logging/otel/config" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/pkg/version" ) var Initializer initmgr.IInitializer = initmgr.NewInitializer(initialize, finalize) diff --git a/cmd/storageserv/handler/reqhandler.go b/cmd/storageserv/handler/reqhandler.go index 9c8fe70e..a029b790 100644 --- a/cmd/storageserv/handler/reqhandler.go +++ b/cmd/storageserv/handler/reqhandler.go @@ -20,12 +20,12 @@ package handler import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/storage" - "juno/pkg/io" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/storage" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" ) var _ io.IRequestHandler = (*RequestHandler)(nil) diff --git a/cmd/storageserv/main.go b/cmd/storageserv/main.go index 271a0523..1c7fb879 100644 --- a/cmd/storageserv/main.go +++ b/cmd/storageserv/main.go @@ -19,7 +19,7 @@ package main -import "juno/cmd/storageserv/app" +import "github.com/paypal/junodb/cmd/storageserv/app" func main() { app.Main() diff --git a/cmd/storageserv/redist/config.go b/cmd/storageserv/redist/config.go index 48aa4ea5..4134fc8a 100644 --- a/cmd/storageserv/redist/config.go +++ b/cmd/storageserv/redist/config.go @@ -20,9 +20,10 @@ package redist import ( - "juno/pkg/io" - "juno/pkg/util" "time" + + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" ) type Config struct { diff --git a/cmd/storageserv/redist/ratelimiter.go b/cmd/storageserv/redist/ratelimiter.go index b98359a8..5cf06cc0 100644 --- a/cmd/storageserv/redist/ratelimiter.go +++ b/cmd/storageserv/redist/ratelimiter.go @@ -20,8 +20,9 @@ package redist import ( - "juno/third_party/forked/golang/glog" "time" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // A variantion of token bucket algorithm diff --git a/cmd/storageserv/redist/redist.go b/cmd/storageserv/redist/redist.go index d4d6a9d7..baf3fd43 100644 --- a/cmd/storageserv/redist/redist.go +++ b/cmd/storageserv/redist/redist.go @@ -26,13 +26,13 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/etcd" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/shard" - redistst "juno/pkg/stats/redist" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + redistst "github.com/paypal/junodb/pkg/stats/redist" ) type IDBRedistHandler interface { diff --git a/cmd/storageserv/redist/replicator.go b/cmd/storageserv/redist/replicator.go index c7a28a56..4ea068c8 100644 --- a/cmd/storageserv/redist/replicator.go +++ b/cmd/storageserv/redist/replicator.go @@ -24,14 +24,14 @@ import ( "sync" "time" - cerr "juno/pkg/errors" - "juno/pkg/etcd" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/shard" - redistst "juno/pkg/stats/redist" - - "juno/third_party/forked/golang/glog" + cerr "github.com/paypal/junodb/pkg/errors" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + redistst "github.com/paypal/junodb/pkg/stats/redist" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type Replicator struct { diff --git a/cmd/storageserv/redist/reqctx.go b/cmd/storageserv/redist/reqctx.go index 249abd99..f0edfaec 100644 --- a/cmd/storageserv/redist/reqctx.go +++ b/cmd/storageserv/redist/reqctx.go @@ -24,12 +24,12 @@ import ( "io" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - . "juno/pkg/io" - "juno/pkg/proto" - redistst "juno/pkg/stats/redist" - "juno/pkg/util" + . "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + redistst "github.com/paypal/junodb/pkg/stats/redist" + "github.com/paypal/junodb/pkg/util" ) type RedistRequestContext struct { diff --git a/cmd/storageserv/stats/htmlsect.go b/cmd/storageserv/stats/htmlsect.go index 86d45177..11d02fbc 100644 --- a/cmd/storageserv/stats/htmlsect.go +++ b/cmd/storageserv/stats/htmlsect.go @@ -25,8 +25,8 @@ import ( "html/template" "time" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/stats" ) type ( diff --git a/cmd/storageserv/stats/htmltmpl.go b/cmd/storageserv/stats/htmltmpl.go index 5fbe57ed..687ce5fd 100644 --- a/cmd/storageserv/stats/htmltmpl.go +++ b/cmd/storageserv/stats/htmltmpl.go @@ -23,7 +23,7 @@ import ( "fmt" "html/template" - "juno/pkg/stats" + "github.com/paypal/junodb/pkg/stats" ) var ( diff --git a/cmd/storageserv/stats/httphandler.go b/cmd/storageserv/stats/httphandler.go index e4b1608a..b36d8eed 100644 --- a/cmd/storageserv/stats/httphandler.go +++ b/cmd/storageserv/stats/httphandler.go @@ -25,11 +25,11 @@ import ( "github.com/BurntSushi/toml" - "juno/cmd/proxy/stats/qry" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/storage/db" - "juno/pkg/stats" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/proxy/stats/qry" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/version" ) var ( diff --git a/cmd/storageserv/stats/monhandler.go b/cmd/storageserv/stats/monhandler.go index d965aa1b..0eb335b5 100644 --- a/cmd/storageserv/stats/monhandler.go +++ b/cmd/storageserv/stats/monhandler.go @@ -29,12 +29,12 @@ import ( "strconv" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/stats" - "juno/pkg/version" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/version" ) type ( diff --git a/cmd/storageserv/stats/shmstats/shmstats.go b/cmd/storageserv/stats/shmstats/shmstats.go index 66b1e7d3..87ecfdc8 100644 --- a/cmd/storageserv/stats/shmstats/shmstats.go +++ b/cmd/storageserv/stats/shmstats/shmstats.go @@ -32,10 +32,10 @@ import ( "time" "unsafe" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/pkg/stats" ) const ( diff --git a/cmd/storageserv/stats/shmstatswr.go b/cmd/storageserv/stats/shmstatswr.go index 042e0b39..d2fb50c7 100644 --- a/cmd/storageserv/stats/shmstatswr.go +++ b/cmd/storageserv/stats/shmstatswr.go @@ -25,8 +25,8 @@ import ( "time" "unsafe" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/stats" ) var ( diff --git a/cmd/storageserv/stats/statelog.go b/cmd/storageserv/stats/statelog.go index 723cf7e9..66d27b6f 100644 --- a/cmd/storageserv/stats/statelog.go +++ b/cmd/storageserv/stats/statelog.go @@ -31,9 +31,9 @@ import ( "syscall" "time" - "juno/cmd/storageserv/storage/db" - "juno/pkg/proto" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/stats" ) const ( @@ -46,7 +46,7 @@ const ( kNumRequestTypes ) -//Exponential Moving Average (EMA) +// Exponential Moving Average (EMA) var ( statsNumRequests uint64 statsNumRequestsPrev uint64 diff --git a/cmd/storageserv/stats/statsinit.go b/cmd/storageserv/stats/statsinit.go index d1e2ed95..8b7f4cfe 100644 --- a/cmd/storageserv/stats/statsinit.go +++ b/cmd/storageserv/stats/statsinit.go @@ -22,11 +22,11 @@ package stats import ( "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/debug" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/debug" ) func InitForManager(numChildren int) (err error) { diff --git a/cmd/storageserv/stats/statslogger.go b/cmd/storageserv/stats/statslogger.go index a36ca100..79ca3643 100644 --- a/cmd/storageserv/stats/statslogger.go +++ b/cmd/storageserv/stats/statslogger.go @@ -29,13 +29,13 @@ import ( "path/filepath" "time" - // "juno/third_party/forked/golang/glog" + // "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/stats" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/stats" ) var ( diff --git a/cmd/storageserv/storage/bench_test.go b/cmd/storageserv/storage/bench_test.go index 90070c04..580fce6e 100644 --- a/cmd/storageserv/storage/bench_test.go +++ b/cmd/storageserv/storage/bench_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) func BenchmarkSet(b *testing.B) { diff --git a/cmd/storageserv/storage/create_test.go b/cmd/storageserv/storage/create_test.go index 25dd5d47..77cd1d26 100644 --- a/cmd/storageserv/storage/create_test.go +++ b/cmd/storageserv/storage/create_test.go @@ -24,7 +24,7 @@ import ( "testing" "time" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) var ( diff --git a/cmd/storageserv/storage/db/config.go b/cmd/storageserv/storage/db/config.go index f7df81f7..eb7ddd95 100644 --- a/cmd/storageserv/storage/db/config.go +++ b/cmd/storageserv/storage/db/config.go @@ -26,8 +26,8 @@ import ( "math/rand" "os" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" ) ///TODO need to add validation @@ -242,7 +242,7 @@ var defaultFlashConfig = Config{ var DBConfig = defaultFlashConfig -//Note: rocksdb C binding does not support getters for option types +// Note: rocksdb C binding does not support getters for option types func NewRocksDBptions() *gorocksdb.Options { options := gorocksdb.NewDefaultOptions() diff --git a/cmd/storageserv/storage/db/db.go b/cmd/storageserv/storage/db/db.go index 60b4d8b1..ed67979a 100644 --- a/cmd/storageserv/storage/db/db.go +++ b/cmd/storageserv/storage/db/db.go @@ -22,8 +22,8 @@ package db import ( "io" - "juno/cmd/storageserv/redist" - "juno/pkg/shard" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/pkg/shard" ) type IDatabase interface { diff --git a/cmd/storageserv/storage/db/dbcopy/cmd.go b/cmd/storageserv/storage/db/dbcopy/cmd.go index 3c66333a..c1fde68d 100644 --- a/cmd/storageserv/storage/db/dbcopy/cmd.go +++ b/cmd/storageserv/storage/db/dbcopy/cmd.go @@ -22,7 +22,7 @@ package main import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type CmdLine struct { diff --git a/cmd/storageserv/storage/db/dbcopy/compact.go b/cmd/storageserv/storage/db/dbcopy/compact.go index c5541641..fc280869 100644 --- a/cmd/storageserv/storage/db/dbcopy/compact.go +++ b/cmd/storageserv/storage/db/dbcopy/compact.go @@ -21,7 +21,8 @@ package main import ( "bytes" - "juno/third_party/forked/golang/glog" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type CompactionFilter struct { diff --git a/cmd/storageserv/storage/db/dbcopy/config.go b/cmd/storageserv/storage/db/dbcopy/config.go index a1834ee4..7fe3da6b 100644 --- a/cmd/storageserv/storage/db/dbcopy/config.go +++ b/cmd/storageserv/storage/db/dbcopy/config.go @@ -28,9 +28,9 @@ import ( "github.com/BurntSushi/toml" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/storage/db" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var cfg = config.Config{ diff --git a/cmd/storageserv/storage/db/dbcopy/dbclient.go b/cmd/storageserv/storage/db/dbcopy/dbclient.go index d6b27c85..bfeae710 100644 --- a/cmd/storageserv/storage/db/dbcopy/dbclient.go +++ b/cmd/storageserv/storage/db/dbcopy/dbclient.go @@ -27,11 +27,11 @@ import ( "path/filepath" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/storageserv/storage/db" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/util" ) type DbClient struct { diff --git a/cmd/storageserv/storage/db/dbcopy/main.go b/cmd/storageserv/storage/db/dbcopy/main.go index d0a767db..6c288aee 100644 --- a/cmd/storageserv/storage/db/dbcopy/main.go +++ b/cmd/storageserv/storage/db/dbcopy/main.go @@ -31,7 +31,7 @@ import ( "strings" "sync" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func parseKeyRange(key string) (start int, stop int) { diff --git a/cmd/storageserv/storage/db/debug.go b/cmd/storageserv/storage/db/debug.go index 57f32f91..e73a7485 100644 --- a/cmd/storageserv/storage/db/debug.go +++ b/cmd/storageserv/storage/db/debug.go @@ -28,7 +28,7 @@ import ( "sync" "unsafe" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" ) var ( diff --git a/cmd/storageserv/storage/db/record.go b/cmd/storageserv/storage/db/record.go index 9ae2675d..86557a3c 100644 --- a/cmd/storageserv/storage/db/record.go +++ b/cmd/storageserv/storage/db/record.go @@ -22,39 +22,38 @@ Package db implements Juno storage interfaces with gorocksdb. Record Encoding Format - Offset | Field | Size - --------+---------------------------------+--------------- - 0 | encoding version | 1 byte - --------+---------------------------------+--------------- - 1 | flag | 1 byte - --------+---------------------------------+--------------- - 2 | reserved | 2 bytes - --------+---------------------------------+--------------- - 4 | expiration time | 4 bytes - --------+---------------------------------+--------------- - 8 | version | 4 bytes - --------+---------------------------------+--------------- - 12 | creation time | 4 bytes - --------+---------------------------------+--------------- - 16 | last modification time | 8 bytes - --------+---------------------------------+--------------- - 24 | request Id of the last modifier | 16 bytes - --------+---------------------------------+--------------- - 40 | request Id of the originator | 16 bytes - --------+---------------------------------+--------------- - 56 | encapsulating payload | ... - - Record Flag - bit | 0| 1| 2| 3| 4| 5| 6| 7 - ------+------------+------------+------------+------------+------------+------------+------------+------------+ - | MarkDelete | - + Offset | Field | Size + --------+---------------------------------+--------------- + 0 | encoding version | 1 byte + --------+---------------------------------+--------------- + 1 | flag | 1 byte + --------+---------------------------------+--------------- + 2 | reserved | 2 bytes + --------+---------------------------------+--------------- + 4 | expiration time | 4 bytes + --------+---------------------------------+--------------- + 8 | version | 4 bytes + --------+---------------------------------+--------------- + 12 | creation time | 4 bytes + --------+---------------------------------+--------------- + 16 | last modification time | 8 bytes + --------+---------------------------------+--------------- + 24 | request Id of the last modifier | 16 bytes + --------+---------------------------------+--------------- + 40 | request Id of the originator | 16 bytes + --------+---------------------------------+--------------- + 56 | encapsulating payload | ... + + Record Flag + bit | 0| 1| 2| 3| 4| 5| 6| 7 + ------+------------+------------+------------+------------+------------+------------+------------+------------+ + | MarkDelete | Storage Key Format - ----------------------------+----------- +-------- - namespace length (1 byte) | namespace | key - ----------------------------+----------- +-------- + ----------------------------+----------- +-------- + namespace length (1 byte) | namespace | key + ----------------------------+----------- +-------- */ package db @@ -66,12 +65,12 @@ import ( "io" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/proto" - "juno/pkg/shard" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/util" ) const ( @@ -234,7 +233,7 @@ func (rec *Record) EncodeToBuffer(buffer *bytes.Buffer) error { return nil } -///TODO validation. the slices +// /TODO validation. the slices func (rec *Record) Decode(data []byte) error { if data == nil || len(data) < kSzHeader { return errors.New("Decoding error: empty") diff --git a/cmd/storageserv/storage/db/recordid.go b/cmd/storageserv/storage/db/recordid.go index 8ff6103e..b46c5c1f 100644 --- a/cmd/storageserv/storage/db/recordid.go +++ b/cmd/storageserv/storage/db/recordid.go @@ -23,9 +23,9 @@ import ( "bytes" "encoding/binary" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/shard" + "github.com/paypal/junodb/pkg/shard" ) var enableMircoShardId bool = false // default false for backward compatibility diff --git a/cmd/storageserv/storage/db/recordid_test.go b/cmd/storageserv/storage/db/recordid_test.go index 29f07345..1da0f86d 100644 --- a/cmd/storageserv/storage/db/recordid_test.go +++ b/cmd/storageserv/storage/db/recordid_test.go @@ -22,8 +22,9 @@ package db import ( "bytes" "fmt" - "juno/pkg/shard" "testing" + + "github.com/paypal/junodb/pkg/shard" ) func TestNoMicroShard(t *testing.T) { diff --git a/cmd/storageserv/storage/db/rocksdb.go b/cmd/storageserv/storage/db/rocksdb.go index 11b1d13c..dd5a29bb 100644 --- a/cmd/storageserv/storage/db/rocksdb.go +++ b/cmd/storageserv/storage/db/rocksdb.go @@ -28,14 +28,14 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" - - "juno/cmd/storageserv/redist" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/shard" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" + + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" ) var ( @@ -92,7 +92,7 @@ func GetPrefixDB() *ShardingByPrefix { return nil } -///TODO xuli dbDir... +// /TODO xuli dbDir... func newDBSharding(numShards int, numMicroShards int, numMicroShardGroups int, numPrefixDbs int, dbnamePrefix string) (sharding IDBSharding) { if numPrefixDbs > 0 { // Use prefix key shardFilters := make([]*ShardFilter, numPrefixDbs, numPrefixDbs) @@ -115,7 +115,7 @@ func newDBSharding(numShards int, numMicroShards int, numMicroShardGroups int, n return } -///TODO dbDir... +// /TODO dbDir... func newRocksDB(numShards int, numMicroShards int, numMicroShardGroups int, numPrefixDbs int, zoneId int, nodeId int, shardMap shard.Map) *RocksDB { db := &RocksDB{ zoneId: zoneId, diff --git a/cmd/storageserv/storage/db/sharding.go b/cmd/storageserv/storage/db/sharding.go index bfc3eedf..b24723bb 100644 --- a/cmd/storageserv/storage/db/sharding.go +++ b/cmd/storageserv/storage/db/sharding.go @@ -23,10 +23,10 @@ import ( "io" "time" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/storageserv/redist" - "juno/pkg/shard" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/pkg/shard" ) type IDBSharding interface { diff --git a/cmd/storageserv/storage/db/shardingByInstance.go b/cmd/storageserv/storage/db/shardingByInstance.go index fcd95a99..0a7dfbe4 100644 --- a/cmd/storageserv/storage/db/shardingByInstance.go +++ b/cmd/storageserv/storage/db/shardingByInstance.go @@ -25,13 +25,13 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/storageserv/redist" - "juno/pkg/shard" - redistst "juno/pkg/stats/redist" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/pkg/shard" + redistst "github.com/paypal/junodb/pkg/stats/redist" + "github.com/paypal/junodb/pkg/util" ) type ShardingByInstance struct { diff --git a/cmd/storageserv/storage/db/shardingByPrefix.go b/cmd/storageserv/storage/db/shardingByPrefix.go index fefd006d..e32988dc 100644 --- a/cmd/storageserv/storage/db/shardingByPrefix.go +++ b/cmd/storageserv/storage/db/shardingByPrefix.go @@ -28,13 +28,13 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - "juno/cmd/storageserv/redist" - "juno/pkg/shard" - redistst "juno/pkg/stats/redist" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/pkg/shard" + redistst "github.com/paypal/junodb/pkg/stats/redist" + "github.com/paypal/junodb/pkg/util" ) type ShardFilter struct { diff --git a/cmd/storageserv/storage/delete_test.go b/cmd/storageserv/storage/delete_test.go index 791add9c..969cb74c 100644 --- a/cmd/storageserv/storage/delete_test.go +++ b/cmd/storageserv/storage/delete_test.go @@ -24,8 +24,8 @@ import ( "testing" "time" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/cmd/storageserv/storage/get_test.go b/cmd/storageserv/storage/get_test.go index 1143f49d..150bb479 100644 --- a/cmd/storageserv/storage/get_test.go +++ b/cmd/storageserv/storage/get_test.go @@ -25,8 +25,8 @@ package storage import ( "testing" - "juno/pkg/proto" - "juno/test/testutil" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" ) var ( diff --git a/cmd/storageserv/storage/lock.go b/cmd/storageserv/storage/lock.go index 8b781cf8..19c14ccd 100644 --- a/cmd/storageserv/storage/lock.go +++ b/cmd/storageserv/storage/lock.go @@ -22,12 +22,12 @@ package storage import ( "sync" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/storage/db" - "juno/pkg/logging" - "juno/pkg/proto" - "juno/pkg/shard" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" ) var ( diff --git a/cmd/storageserv/storage/proc.go b/cmd/storageserv/storage/proc.go index 647cbbe8..c744c5c8 100644 --- a/cmd/storageserv/storage/proc.go +++ b/cmd/storageserv/storage/proc.go @@ -26,20 +26,20 @@ import ( "runtime" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/storageserv/config" - ssstats "juno/cmd/storageserv/stats" - "juno/cmd/storageserv/storage/db" - "juno/pkg/debug" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" - "juno/pkg/shard" - "juno/pkg/stats" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/storageserv/config" + ssstats "github.com/paypal/junodb/cmd/storageserv/stats" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/stats" + "github.com/paypal/junodb/pkg/util" ) const ( @@ -116,19 +116,13 @@ func (p *reqProcCtxT) OnComplete() { calData.AddOpRequestResponse(&p.request, &p.response).AddRequestHandleTime(rhtus) cal.AtomicTransaction(cal.TxnTypeAPI, opcode.String(), calst.CalStatus(), rht, calData.Bytes()) } - if otel.IsEnabled() { - otel.RecordOperation(opcode.String(), p.response.GetOpStatus().String(), int64(rhtus)) - opst := p.response.GetOpStatus() - calst := logging.CalStatus(opst) - if (opst == proto.OpStatusInconsistent) || calst.NotSuccess() { - otel.RecordCount(otel.ProcErr, []otel.Tags{{otel.Operation, opcode.String() + "_" + opst.String()}, {otel.Status, otel.StatusError}}) - } - } if (opst == proto.OpStatusInconsistent) || calst.NotSuccess() { cal.Event("ProcErr", opcode.String()+"_"+opst.String(), cal.StatusSuccess, nil) } } + otel.RecordOperation(opcode.String(), p.response.GetOpStatus(), int64(rhtus)) + if p.cacheable { if p.prepareCtx != nil { if p.prepareCtx.cacheable { diff --git a/cmd/storageserv/storage/set_test.go b/cmd/storageserv/storage/set_test.go index 4cba2f4b..89b5b24e 100644 --- a/cmd/storageserv/storage/set_test.go +++ b/cmd/storageserv/storage/set_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) var ( diff --git a/cmd/storageserv/storage/setup_test.go b/cmd/storageserv/storage/setup_test.go index ad72be99..1eebff06 100644 --- a/cmd/storageserv/storage/setup_test.go +++ b/cmd/storageserv/storage/setup_test.go @@ -24,11 +24,11 @@ import ( "os" "testing" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/storage/db" - "juno/pkg/shard" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/shard" ) func testSetup() { diff --git a/cmd/storageserv/storage/storage.go b/cmd/storageserv/storage/storage.go index 62d576c7..f2010843 100644 --- a/cmd/storageserv/storage/storage.go +++ b/cmd/storageserv/storage/storage.go @@ -27,21 +27,21 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/dbscanserv/patch" - "juno/cmd/storageserv/config" - "juno/cmd/storageserv/redist" - "juno/cmd/storageserv/storage/db" - "juno/cmd/storageserv/watcher" - "juno/pkg/cluster" - "juno/pkg/debug" - "juno/pkg/etcd" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/shard" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/dbscanserv/patch" + "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/cmd/storageserv/redist" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/cmd/storageserv/watcher" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/util" ) var ( @@ -1125,7 +1125,7 @@ func TruncateExpired() { } // TODO: revisit... -//Used to detect replication conflict. Not for conditional update +// Used to detect replication conflict. Not for conditional update func isConflict(request *proto.OperationalMessage, rec *db.Record) (conflict bool) { lmt := request.GetLastModificationTime() if lmt != 0 { diff --git a/cmd/storageserv/storage/storage_test.go b/cmd/storageserv/storage/storage_test.go index 3a30b8e9..e3b89ac2 100644 --- a/cmd/storageserv/storage/storage_test.go +++ b/cmd/storageserv/storage/storage_test.go @@ -27,12 +27,12 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/storageserv/storage/db" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/shard" + "github.com/paypal/junodb/cmd/storageserv/storage/db" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/shard" ) const ( diff --git a/cmd/storageserv/storage/update_test.go b/cmd/storageserv/storage/update_test.go index 7ec45b3a..25703ef0 100644 --- a/cmd/storageserv/storage/update_test.go +++ b/cmd/storageserv/storage/update_test.go @@ -23,8 +23,8 @@ import ( "testing" "time" - "juno/pkg/proto" - // "juno/test/testutil" + "github.com/paypal/junodb/pkg/proto" + // "github.com/paypal/junodb/test/testutil" ) var ( diff --git a/cmd/storageserv/watcher/watcher.go b/cmd/storageserv/watcher/watcher.go index b4a12206..f7ac87ef 100644 --- a/cmd/storageserv/watcher/watcher.go +++ b/cmd/storageserv/watcher/watcher.go @@ -27,13 +27,13 @@ import ( "strconv" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" clientv3 "go.etcd.io/etcd/client/v3" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/shard" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/shard" ) // watch for the following etcd changes diff --git a/cmd/tools/cmd/cfg/cfggen.go b/cmd/tools/cmd/cfg/cfggen.go index 856865cf..9b12e917 100644 --- a/cmd/tools/cmd/cfg/cfggen.go +++ b/cmd/tools/cmd/cfg/cfggen.go @@ -26,9 +26,9 @@ import ( "github.com/BurntSushi/toml" - "juno/cmd/proxy/config" - sscfg "juno/cmd/storageserv/config" - "juno/pkg/cmd" + "github.com/paypal/junodb/cmd/proxy/config" + sscfg "github.com/paypal/junodb/cmd/storageserv/config" + "github.com/paypal/junodb/pkg/cmd" ) type cfgTypeT int diff --git a/cmd/tools/cmd/cfg/conf.go b/cmd/tools/cmd/cfg/conf.go index add9a23c..3d17fb07 100644 --- a/cmd/tools/cmd/cfg/conf.go +++ b/cmd/tools/cmd/cfg/conf.go @@ -25,8 +25,8 @@ import ( "os" "strings" - "juno/pkg/cfg" - "juno/pkg/cmd" + "github.com/paypal/junodb/pkg/cfg" + "github.com/paypal/junodb/pkg/cmd" ) type cmdConfUnify struct { diff --git a/cmd/tools/cmd/cfg/rtcfg.go b/cmd/tools/cmd/cfg/rtcfg.go index 70b30bc3..b1bdb2e0 100644 --- a/cmd/tools/cmd/cfg/rtcfg.go +++ b/cmd/tools/cmd/cfg/rtcfg.go @@ -26,11 +26,11 @@ import ( "os" "time" - "juno/cmd/proxy/config" - "juno/pkg/cfg" - "juno/pkg/client" - "juno/pkg/cmd" - "juno/pkg/etcd" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/cfg" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/etcd" ) const ( diff --git a/cmd/tools/cmd/cli/cli.go b/cmd/tools/cmd/cli/cli.go index 8e1c5fec..d90f1490 100644 --- a/cmd/tools/cmd/cli/cli.go +++ b/cmd/tools/cmd/cli/cli.go @@ -26,17 +26,17 @@ import ( "os" "time" - "juno/pkg/logging/cal" - "juno/pkg/logging/cal/config" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" uuid "github.com/satori/go.uuid" - "juno/pkg/client" - "juno/pkg/cmd" - "juno/pkg/sec" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/util" ) const ( diff --git a/cmd/tools/cmd/cli/sscli.go b/cmd/tools/cmd/cli/sscli.go index 05494edf..2d29078e 100644 --- a/cmd/tools/cmd/cli/sscli.go +++ b/cmd/tools/cmd/cli/sscli.go @@ -25,15 +25,15 @@ import ( "os" "time" - // "juno/third_party/forked/golang/glog" + // "github.com/paypal/junodb/third_party/forked/golang/glog" uuid "github.com/satori/go.uuid" - "juno/internal/cli" - "juno/pkg/client" - "juno/pkg/cluster" - "juno/pkg/cmd" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) const ( diff --git a/cmd/tools/cmd/insp/inspmsg.go b/cmd/tools/cmd/insp/inspmsg.go index 94f742bc..97118dba 100644 --- a/cmd/tools/cmd/insp/inspmsg.go +++ b/cmd/tools/cmd/insp/inspmsg.go @@ -25,8 +25,8 @@ import ( "fmt" "os" - "juno/pkg/cmd" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/proto" ) type cmdInspMsgT struct { diff --git a/cmd/tools/cmd/insp/insprid.go b/cmd/tools/cmd/insp/insprid.go index 95249a55..791744ad 100644 --- a/cmd/tools/cmd/insp/insprid.go +++ b/cmd/tools/cmd/insp/insprid.go @@ -26,10 +26,10 @@ import ( uuid "github.com/satori/go.uuid" - "juno/pkg/cmd" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/cmd/tools/cmd/insp/ssgrp.go b/cmd/tools/cmd/insp/ssgrp.go index 20bd047a..2d0bf48f 100644 --- a/cmd/tools/cmd/insp/ssgrp.go +++ b/cmd/tools/cmd/insp/ssgrp.go @@ -23,13 +23,13 @@ import ( "encoding/hex" "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - "juno/pkg/cluster" - "juno/pkg/cmd" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/cmd/tools/cmd/stats/proxystats.go b/cmd/tools/cmd/stats/proxystats.go index 4760dc82..92c13bd1 100644 --- a/cmd/tools/cmd/stats/proxystats.go +++ b/cmd/tools/cmd/stats/proxystats.go @@ -23,8 +23,8 @@ import ( "fmt" "os" - "juno/cmd/proxy/stats/shmstats" - "juno/pkg/cmd" + "github.com/paypal/junodb/cmd/proxy/stats/shmstats" + "github.com/paypal/junodb/pkg/cmd" ) var _ cmd.ICommand = (*CmdProxyStats)(nil) diff --git a/cmd/tools/cmd/stats/storagestats.go b/cmd/tools/cmd/stats/storagestats.go index 03ee76c2..5bfa84f3 100644 --- a/cmd/tools/cmd/stats/storagestats.go +++ b/cmd/tools/cmd/stats/storagestats.go @@ -23,8 +23,8 @@ import ( "fmt" "os" - "juno/cmd/storageserv/stats/shmstats" - "juno/pkg/cmd" + "github.com/paypal/junodb/cmd/storageserv/stats/shmstats" + "github.com/paypal/junodb/pkg/cmd" ) var _ cmd.ICommand = (*CmdStorageStats)(nil) diff --git a/cmd/tools/goldendata/client.go b/cmd/tools/goldendata/client.go index b66d2208..c0202423 100644 --- a/cmd/tools/goldendata/client.go +++ b/cmd/tools/goldendata/client.go @@ -25,10 +25,10 @@ import ( "strings" "time" - "juno/pkg/client" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/util" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type Duration = util.Duration diff --git a/cmd/tools/goldendata/goldenset.go b/cmd/tools/goldendata/goldenset.go index 22d74747..ef973579 100644 --- a/cmd/tools/goldendata/goldenset.go +++ b/cmd/tools/goldendata/goldenset.go @@ -21,7 +21,8 @@ package gld import ( "fmt" - "juno/pkg/util" + + "github.com/paypal/junodb/pkg/util" ) type KEY []byte diff --git a/cmd/tools/goldendata/redistset.go b/cmd/tools/goldendata/redistset.go index 6f80a52e..b81e79c5 100644 --- a/cmd/tools/goldendata/redistset.go +++ b/cmd/tools/goldendata/redistset.go @@ -21,9 +21,10 @@ package gld import ( "fmt" - "juno/pkg/util" "strconv" "strings" + + "github.com/paypal/junodb/pkg/util" ) type RedistSet struct { diff --git a/cmd/tools/goldentool/goldentool.go b/cmd/tools/goldentool/goldentool.go index ec957af0..b387f66f 100644 --- a/cmd/tools/goldentool/goldentool.go +++ b/cmd/tools/goldentool/goldentool.go @@ -25,8 +25,8 @@ import ( "os" "path/filepath" - "juno/cmd/tools/goldendata" - "juno/third_party/forked/golang/glog" + gld "github.com/paypal/junodb/cmd/tools/goldendata" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func main() { diff --git a/cmd/tools/junocfg/junocfg.go b/cmd/tools/junocfg/junocfg.go index 2e5c440b..2fba125a 100644 --- a/cmd/tools/junocfg/junocfg.go +++ b/cmd/tools/junocfg/junocfg.go @@ -22,8 +22,8 @@ package main import ( "fmt" - "juno/cmd/tools/cmd/cfg" - "juno/pkg/cmd" + "github.com/paypal/junodb/cmd/tools/cmd/cfg" + "github.com/paypal/junodb/pkg/cmd" ) func main() { diff --git a/cmd/tools/junocli/junocli.go b/cmd/tools/junocli/junocli.go index fa972002..1d39cb50 100644 --- a/cmd/tools/junocli/junocli.go +++ b/cmd/tools/junocli/junocli.go @@ -22,11 +22,11 @@ package main import ( "fmt" - _ "juno/cmd/tools/cmd/cfg" - _ "juno/cmd/tools/cmd/cli" - _ "juno/cmd/tools/cmd/insp" - "juno/pkg/cmd" - "juno/pkg/logging/cal" + _ "github.com/paypal/junodb/cmd/tools/cmd/cfg" + _ "github.com/paypal/junodb/cmd/tools/cmd/cli" + _ "github.com/paypal/junodb/cmd/tools/cmd/insp" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/logging/cal" ) func main() { diff --git a/cmd/tools/junostats/junostats.go b/cmd/tools/junostats/junostats.go index 0e19cc66..2b54b756 100644 --- a/cmd/tools/junostats/junostats.go +++ b/cmd/tools/junostats/junostats.go @@ -22,8 +22,8 @@ package main import ( "fmt" - "juno/cmd/tools/cmd/stats" - "juno/pkg/cmd" + "github.com/paypal/junodb/cmd/tools/cmd/stats" + "github.com/paypal/junodb/pkg/cmd" ) func main() { diff --git a/docker/build.sh b/docker/build.sh index c7c701e3..e8afd73a 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -57,7 +57,23 @@ make image_tag=${image_tag} docker_repo=${docker_repo} source_repo=${source_repo # Set the app version using image_tag in manifest/.env -sed -i "s#.*VERSION=.*#VERSION=${image_tag}#g" ${wd}/manifest/.env +# Get the kernel name +kernel=$(uname -s) + +# Set the sed command based on the operating system +if [[ $kernel == "Linux" ]]; then + sed_command="sed -i 's#.*VERSION=.*#VERSION=${image_tag}#g' ${wd}/manifest/.env" +elif [[ $kernel == "Darwin" ]]; then + sed_command="sed -i '' 's#.*VERSION=.*#VERSION=${image_tag}#g' ${wd}/manifest/.env" +elif [[ $kernel == "CYGWIN"* || $kernel == "MINGW"* ]]; then + sed_command="sed -i 's#.*VERSION=.*#VERSION=${image_tag}#g' ${wd}/manifest/.env" +else + echo "Unknown operating system." + exit 1 +fi + +# Run the sed command +eval "$sed_command" # Generate the test secrets to initialize proxy manifest/config/secrets/gensecrets.sh diff --git a/docker/build/Dockerfile b/docker/build/Dockerfile index 2aebfb69..7f3a9df9 100644 --- a/docker/build/Dockerfile +++ b/docker/build/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 AS juno-base +FROM ubuntu:20.04 AS juno-base USER root RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -qq install -y \ cmake \ diff --git a/docker/build/build.sh b/docker/build/build.sh index 97efb62c..4e63cd6d 100755 --- a/docker/build/build.sh +++ b/docker/build/build.sh @@ -18,22 +18,24 @@ # limitations under the License. # +set -eo pipefail +cd "$(dirname "$0")" export CGO_CFLAGS="-I/usr/local/include" export CGO_LDFLAGS="-L/usr/local/lib -lrocksdb -lstdc++ -lm -lrt -lpthread -ldl" juno_executables="\ - juno/cmd/proxy \ - juno/cmd/storageserv \ - juno/cmd/clustermgr/clusterctl \ - juno/cmd/dbscanserv \ - juno/cmd/dbscanserv/junoctl \ - juno/cmd/tools/junostats \ - juno/cmd/tools/junocfg \ - juno/cmd/tools/junocli \ - juno/test/drv/junoload \ - juno/test/drv/bulkload \ - juno/cmd/storageserv/storage/db/dbcopy \ + github.com/paypal/junodb/cmd/proxy \ + github.com/paypal/junodb/cmd/storageserv \ + github.com/paypal/junodb/cmd/clustermgr/clusterctl \ + github.com/paypal/junodb/cmd/dbscanserv \ + github.com/paypal/junodb/cmd/dbscanserv/junoctl \ + github.com/paypal/junodb/cmd/tools/junostats \ + github.com/paypal/junodb/cmd/tools/junocfg \ + github.com/paypal/junodb/cmd/tools/junocli \ + github.com/paypal/junodb/test/drv/junoload \ + github.com/paypal/junodb/test/drv/bulkload \ + github.com/paypal/junodb/cmd/storageserv/storage/db/dbcopy \ " export PATH=/usr/local/go/bin:$PATH diff --git a/docker/manifest/config/otel/config.yaml b/docker/manifest/config/otel/config.yaml new file mode 100644 index 00000000..b5de724c --- /dev/null +++ b/docker/manifest/config/otel/config.yaml @@ -0,0 +1,29 @@ +# connfig ref : https://opentelemetry.io/docs/collector/configuration/ +receivers: + otlp: + protocols: + http: + endpoint: "0.0.0.0:4318" + + +exporters: + # Data sources: metrics + prometheus: + endpoint: "0.0.0.0:8889" + namespace: default + send_timestamps: true + metric_expiration: 180m + # resource_to_telemetry_conversion: + # enabled: true + +extensions: + health_check: + pprof: + zpages: + +service: + extensions: [health_check, pprof, zpages] + pipelines: + metrics: + receivers: [otlp] + exporters: [prometheus] diff --git a/docker/manifest/config/prometheus/prometheus.yaml b/docker/manifest/config/prometheus/prometheus.yaml new file mode 100644 index 00000000..cd1efea2 --- /dev/null +++ b/docker/manifest/config/prometheus/prometheus.yaml @@ -0,0 +1,6 @@ +scrape_configs: + - job_name: 'otel' + scrape_interval: 10s + static_configs: + - targets: ['otel:8888'] + - targets: ['otel:8889'] diff --git a/docker/monitoring/docker-compose.yaml b/docker/monitoring/docker-compose.yaml new file mode 100644 index 00000000..e0146bf0 --- /dev/null +++ b/docker/monitoring/docker-compose.yaml @@ -0,0 +1,41 @@ +version: "3" +services: + otel-collector: + container_name: "otel-collector" + image: otel/opentelemetry-collector-contrib + restart: always + command: + - --config=/etc/otelcol-contrib/otel-config.yaml + volumes: + - ./otel-collector-config.yaml:/etc/otelcol-contrib/otel-config.yaml + ports: + - "1888:1888" # pprof extension + - "8888:8888" # Prometheus metrics exposed by the Collector + - "8889:8889" # Prometheus exporter metrics + - "13133:13133" # health_check extension + - "4317:4317" # OTLP gRPC receiver + - "4318:4318" # OTLP http receiver + - "55679:55679" # zpages extension + + prometheus: + image: prom/prometheus + container_name: prometheus + restart: always + command: + - --config.file=/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + - prometheus-data:/prometheus + + grafana: + container_name: grafana + image: grafana/grafana + volumes: + - ./grafana-datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml + ports: + - "3000:3000" + +volumes: + prometheus-data: diff --git a/docker/monitoring/grafana-datasources.yml b/docker/monitoring/grafana-datasources.yml new file mode 100644 index 00000000..22b668e8 --- /dev/null +++ b/docker/monitoring/grafana-datasources.yml @@ -0,0 +1,15 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + uid: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: false + version: 1 + editable: false + jsonData: + httpMethod: GET diff --git a/docker/monitoring/otel-collector-config.yaml b/docker/monitoring/otel-collector-config.yaml new file mode 100644 index 00000000..c0080ff9 --- /dev/null +++ b/docker/monitoring/otel-collector-config.yaml @@ -0,0 +1,32 @@ +receivers: + otlp: + protocols: + http: + +processors: + # batch metrics before sending to reduce API usage + batch: + +exporters: + prometheus: + endpoint: "0.0.0.0:8889" + const_labels: + label: juno + + +# https://github.com/open-telemetry/opentelemetry-collector/blob/main/extension/README.md +extensions: + # responsible for responding to health check calls on behalf of the collector. + health_check: + # fetches the collector’s performance data + pprof: + # serves as an http endpoint that provides live debugging data about instrumented components. + zpages: + +service: + extensions: [health_check, pprof, zpages] + pipelines: + metrics: + receivers: [otlp] + processors: [batch] + exporters: [prometheus] diff --git a/docker/monitoring/prometheus.yml b/docker/monitoring/prometheus.yml new file mode 100644 index 00000000..d543277a --- /dev/null +++ b/docker/monitoring/prometheus.yml @@ -0,0 +1,12 @@ +global: + scrape_interval: 10s + evaluation_interval: 10s + +scrape_configs: + - job_name: 'otel-collector' + static_configs: + - targets: ['otel-collector:8889'] # Otlp + # uncomment to enable prometheus metrics + #- job_name: 'prometheus' + # static_configs: + # - targets: ['localhost:9090'] # Prometheus itself diff --git a/docs/host_expansion.md b/docs/host_expansion.md new file mode 100644 index 00000000..8425258c --- /dev/null +++ b/docs/host_expansion.md @@ -0,0 +1,102 @@ +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +# Juno Host Expansion Instruction +Juno is a high scalable and available distributed key value store. In Juno architecture, the whole storage space is partitioned into a fixed number (e.g. 1024) of logical shards, and shards are mapped to storage nodes within the cluster. When a cluster scaling out or scaling in (storage nodes are either added or removed to/from the cluster), some shards must be redistributed to different nodes to reflect new cluster topology. Following are the instuctions on how to expand(or shrink) the juno storageserv nodes. + +## Expand or Shrink Storage Host +### Step0 (pre-requisite) +Deploy juno storageserv (and or junoserv) to all new boxes + +junostorageserv on all the original boxes need to be up + +Pre-insert data to original cluster so it can be used for later validation(optional but suggested) + +Overall, the expansion contains below steps: +```bash +1. Markdown one zone at a time to stop incoming real time traffic to this zone +2. Run command to update cluster topo to new cluster in etcd +3. Start storageserv on new box for relavant zone. +4. Run command to start redistribution + 4a. if requests failed to forward after serveral auto retry, run resume command to do redistribution again + 4b. if after 3a still some requests fail, restart source storageserv so the failed one can start forward again. +5. Run command to commit if previous steps are all successful. +``` + +Loop through zone0 to zone5 to finish redistribution for all zones +Retrieve pre-inserted data from storageserv for validation (optional) + + +### Step1 +under junoclustercfg, run +```bash + ./clustermgr --config config.toml --cmd zonemarkdown --type set -zone 0 (1,2,3,4) +``` +verify markdown works by checking etcd cluster info (zonemarkdown flag added) and junostorageserv state log +that no new request coming +```bash +--- etcd cluster info shows markdown flag is set --- +run command "export ETCDCTL_API=3; ~/junoclusterserv/etcdctl --endpoints=: --prefix=true get "" | tail -8 " +juno.junoserv_numzones +3 +juno.junoserv_version +1 +juno.junoserv_zonemarkdown (markdown flag is set for zone 0) +0 +juno.root_junoserv +2023-12-05 12:16:17|u20box|/home/deploy/junoclustercfg + +--- junostorageserv/state-logs/current shows the number of incoming requests(req) didn't change, i.e. no new traffic coming --- +12-05 12:39:49 id free used req apt Read D C A RR keys LN compSec compCount pCompKB stall pCPU mCPU pMem mMem +12-05 12:39:49 3-0 453110 42899 34267 98 3303 0 15482 0 0 4338 0 0 0 0 0 0.1 0.2 0.1 15.6 +12-05 12:39:50 3-0 453110 42899 34267 98 3303 0 15482 0 0 4338 0 0 0 0 0 0.1 0.2 0.1 15.6 +12-05 12:39:51 3-0 453110 42899 34267 98 3303 0 15482 0 0 4338 0 0 0 0 0 0.1 0.3 0.1 15.6 +``` + +### Step2 +under junoclustercfg, run +```bash + ./clustermgr -new_config config.toml_new -cmd redist -type prepare -zone 0 (1,2,3,4) +``` +NOTE: A UI monitoring http link will be generated in redistserv.pid. It can be used for monitoring + +### Step3 +start junostorageserv on new box for relavant zone -- zone 0(1,2,3,4) + +### Step4 +under junoclustercfg, run +```bash + ./clustermgr -new_config config.toml_new -ratelimit 5000 -cmd redist -type start_tgt --zone 0 (1,2,3,4) + ./clustermgr -new_config config.toml_new -ratelimit 5000 -cmd redist -type start_src --zone 0 (1,2,3,4) +``` +NOTE: the ratelimit needs to be tuned for each different system. Depending on old/new cluster, the rate setting + will be different. For example,expansion from 5 to 10 boxes or expansion from 5 to 15 boxes, rate will be + different + +#### Step4a (only if requests forward final failed after several auto retry) +under junoclustercfg, run +```bash + ./clustermgr --new_config config.toml_new --cmd redist --type resume -ratelimit 5000 -zone 0(1,2,3,4) +``` + +#### Step4b (only if 4a still doesn't fix the failure) +restart source storageserv and wait for redistribution complete + +### Step5 +under junoclustercfg, run +```bash + ./clustermgr -new_config config.toml_new --cmd redist --type commit -zone 0(1,2,3,4) +``` +Loop around zone0 to zone5 to complete all zones' redistribution + +## Validation (Optional but suggest) + +### Steps +run juno client tool to get shard map which contains ss ip:port +```bash + ./junocli ssgrp -c config.toml_new -hex=false key +``` + +run juno client tool to verify if key exists in the expected ss. ip:port is the one get from previoius command +```bash + ./junocli read -s ip:port key +``` + diff --git a/docs/otel_mon.png b/docs/otel_mon.png new file mode 100644 index 00000000..5fe3292a Binary files /dev/null and b/docs/otel_mon.png differ diff --git a/docs/otel_monitoring.md b/docs/otel_monitoring.md new file mode 100644 index 00000000..6fc58b6c --- /dev/null +++ b/docs/otel_monitoring.md @@ -0,0 +1,59 @@ +## Monitor Juno Metrics using Prometheus + +#### A simple setup to push the metrics on prometheus using otel-collector is shown below. Grafana can be further used to create visualizations from the available metrics. + + + + #### Setup + + ##### Configure proxy and storage to push metrics to otel endpoint + +- Juno proxy and storage services are configured to push the metrics on open telemetry collector endpoint http://localhost:4318/v1/metrics . Add/Update the [OTEL] section in the respective config.toml files + +```yaml +[OTEL] + Enabled = true + Environment = "qa" + Host = "0.0.0.0" + Poolname = "junoserv-ai" + Port = 4318 + Resolution = 10 + UrlPath = "/v1/metrics" + UseTls = false + +``` + +- Now the proxy and storage services are uploading metrics to otel endpoint. + +##### Set up otel-collector, prometheus and grafana +- Open telemetry collector, prometheus and grafana are run as docker containers. +- otel-collector , prometheus and grafana configurations are required to be mounted as volumes in the containers +- docker-compose.yaml and configuration files for each of the services available in junodb/docker/monitoring + + +```bash +cd junodb/docker/monitoring + +docker compose up -d +``` + +- Check the running containers. prometheus, otel-collector and grafana should be running + +```bash +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +bcb1e7ece6b7 prom/prometheus "/bin/prometheus --c…" 3 hours ago Up 3 hours 0.0.0.0:9090->9090/tcp prometheus +c3816c006f85 otel/opentelemetry-collector-contrib "/otelcol-contrib --…" 3 hours ago Up 3 hours 0.0.0.0:1888->1888/tcp, 0.0.0.0:4317-4318->4317-4318/tcp, 0.0.0.0:8888-8889->8888-8889/tcp, 0.0.0.0:13133->13133/tcp, 0.0.0.0:55679->55679/tcp, 55678/tcp otel-collector +e41e33696606 grafana/grafana "/run.sh" 3 hours ago Up 3 hours 0.0.0.0:3000->3000/tcp grafana + +``` + +- Check the promethus server running at :9090 as shown below. Search for juno metrics. + + + + + diff --git a/docs/prometheus.png b/docs/prometheus.png new file mode 100644 index 00000000..d54cc18e Binary files /dev/null and b/docs/prometheus.png differ diff --git a/docs/swaphost.md b/docs/swaphost.md new file mode 100644 index 00000000..6df77992 --- /dev/null +++ b/docs/swaphost.md @@ -0,0 +1,86 @@ +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +# Juno Host Swap Instruction +Bad Juno nodes may have to be swapped out on a live cluster. The node that needs to be swapped can be running etcd (junoclusterserv), or juno storage or both. Following is a step-by-step guide to perform the swap. + +## Swapping a Storage Host +### Step0 (optional) +Pre-insert some data via junocli tool before host swap, after host swap, retrieve data and see if all data are able to be retrieved. + +### Step1 +Deploy junostorageserv (and or junoserv) on New_Host1, both services don't need to be start up, just deploy. +update the junoclustercfg config.toml by changing old box into new box, make a package and deploy it to new box. + +```bash +Old Config New Config +SSHosts=[ SSHosts=[ +# Zone 0 # Zone 0 +[ [ + "Host1" "New_Host1" +], ], +# Zone 1 # Zone 1 +[ [ + "Host2" "Host2" +], ], +# Zone 2 # Zone 2 +[ [ + "Host3" "Host3" +], +# Zone 3 # Zone 3 +[ [ + "Host4" "Host4" +], ], +# Zone 4 # Zone 4 +[ [ + "Host5" "Host5" +] ] +] ] +``` +Make sure storageserv are up on all the boxes other than the bad box. + +### Step2 +If to be replaced box is a bad box, this step can be skipped. If to be replaced box is a good box, shutdown +junostorageserv on to be replaced box, copy rocksdb_junostorageserv from it to new box on the same location. + +### Step3 +On the new box (the cluster config contains New_Host1), from junoclustercfg directory, run ./swaphost.sh. +This step will bump up the junocluster config version in etcd and all the running junoserv and junostorageserv +hosts will update their cluster map accordingly after script run. + +### Step4 +Start up junostorageserv (and or junoserv) on New_Host1. It will fetch the latest junoclustercfg from etcd. + +### Step5 (Optional) +Validation - use junocli to retrieve pre-inserted data, all data should be able to retrieve. + +### Step6 +Once junoserv on New_Host1 works fine, if there is LB in front of junoserv, fix LB to replace Host1 with New_Host1 + +Deploy the updated junoclustercfg package which contains New_Host1 to all the junoclustercfg boxes. All boxes have +same version of junoclustercfg package after that. + +## Swapping host which has etcd server runs on +The etcd cluster has three or five hosts depending on 3 quorum or 5 quorum - Host1^Host2^Host3^Host4^Host5 + +Identify a new host (New_Host1) for the swap. Make sure etcd servers are up on all hosts except the bad one. +Host1 is to be swapped with New_Host1 + +### Step1 +Change the etcdsvr.txt under junoclusterserv +```bash +Old etcdsvr.txt New etcdsvr.txt +[etcdsvr] [etcdsvr] +initial_cluster = "Host1^Host2^Host3^Host4^Host5" initial_cluster = "New_Host1^Host2^Host3^Host4^Host5" +``` +Build the junoclusterserv package and deploy to new box (New_Host1) + +### Step2 +On the old box (Host1), shutdown junoclusterserv by shutdown.sh under junoclusterserv + +On the new box(New_Host1), under junoclusterserv, first run join.sh, then run start.sh to have the new box +join the members of quorum + +### Step3 +Deploy and start the new junoclusterserv package one by one to all other junoclusterserv boxes + +### Step4 +Fix LB of etcd to replace old Host1 with New_Host1. diff --git a/go.mod b/go.mod index b55c9d08..0c138506 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module juno +module github.com/paypal/junodb go 1.18 @@ -12,42 +12,42 @@ require ( github.com/satori/go.uuid v1.2.0 github.com/spaolacci/murmur3 v1.1.0 go.etcd.io/etcd/client/v3 v3.5.4 - go.opentelemetry.io/otel v1.11.2 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 - go.opentelemetry.io/otel/metric v0.34.0 - go.opentelemetry.io/otel/sdk v1.11.2 - go.opentelemetry.io/otel/sdk/metric v0.34.0 + go.opentelemetry.io/otel v1.16.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.39.0 + go.opentelemetry.io/otel/metric v1.16.0 + go.opentelemetry.io/otel/sdk v1.16.0 + go.opentelemetry.io/otel/sdk/metric v0.39.0 go.opentelemetry.io/proto/otlp v0.19.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/protobuf v1.30.0 ) require ( - github.com/golang/protobuf v1.5.2 // indirect - github.com/kr/pretty v0.3.0 // indirect - github.com/rogpeppe/go-internal v1.6.2 // indirect - golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect - golang.org/x/net v0.7.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/rogpeppe/go-internal v1.6.2 // indirect go.etcd.io/etcd/api/v3 v3.5.4 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 // indirect - go.opentelemetry.io/otel/trace v1.11.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect - google.golang.org/grpc v1.51.0 // indirect + golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect + google.golang.org/grpc v1.55.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index 3cd3cb01..f107fb29 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -101,8 +101,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -112,8 +112,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -139,8 +139,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -248,7 +249,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -265,22 +266,22 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= -go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 h1:htgM8vZIF8oPSCxa341e3IZ4yr/sKxgu8KZYllByiVY= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 h1:kpskzLZ60cJ48SJ4uxWa6waBL+4kSV6nVK8rP+QM8Wg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0/go.mod h1:4+x3i62TEegDHuzNva0bMcAN8oUi5w4liGb1d/VgPYo= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 h1:t4Ajxj8JGjxkqoBtbkCOY2cDUl9RwiNE9LPQavooi9U= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0/go.mod h1:WO7omosl4P7JoanH9NgInxDxEn2F2M5YinIh8EyeT8w= -go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8= -go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8= -go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= -go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= -go.opentelemetry.io/otel/sdk/metric v0.34.0 h1:7ElxfQpXCFZlRTvVRTkcUvK8Gt5DC8QzmzsLsO2gdzo= -go.opentelemetry.io/otel/sdk/metric v0.34.0/go.mod h1:l4r16BIqiqPy5rd14kkxllPy/fOI4tWo1jkpD9Z3ffQ= -go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= -go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0 h1:f6BwB2OACc3FCbYVznctQ9V6KK7Vq6CjmYXJ7DeSs4E= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.39.0/go.mod h1:UqL5mZ3qs6XYhDnZaW1Ps4upD+PX6LipH40AoeuIlwU= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.39.0 h1:IZXpCEtI7BbX01DRQEWTGDkvjMB6hEhiEZXS+eg2YqY= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.39.0/go.mod h1:xY111jIZtWb+pUUgT4UiiSonAaY2cD2Ts5zvuKLki3o= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -369,8 +370,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -426,8 +427,8 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -435,8 +436,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -486,7 +487,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -549,8 +550,9 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -568,8 +570,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -583,8 +585,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/cli/ctx.go b/internal/cli/ctx.go index 022dbfd5..56965d87 100644 --- a/internal/cli/ctx.go +++ b/internal/cli/ctx.go @@ -20,9 +20,9 @@ package cli import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) //GetResponse() != nil and GetError() != nil are mutually exclusive diff --git a/internal/cli/proc.go b/internal/cli/proc.go index 5a4719ce..d67c13b9 100644 --- a/internal/cli/proc.go +++ b/internal/cli/proc.go @@ -26,11 +26,11 @@ import ( "syscall" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - junoio "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/util" + junoio "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/internal/cli/processor.go b/internal/cli/processor.go index be505974..cb7ee3ad 100644 --- a/internal/cli/processor.go +++ b/internal/cli/processor.go @@ -25,12 +25,12 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) type IOError struct { diff --git a/internal/cli/recinfo.go b/internal/cli/recinfo.go index 6e3a752e..728bfb42 100644 --- a/internal/cli/recinfo.go +++ b/internal/cli/recinfo.go @@ -22,7 +22,7 @@ package cli import ( "fmt" "io" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) type RecordInfo struct { diff --git a/internal/cli/tracker.go b/internal/cli/tracker.go index 54a30021..28af2b13 100644 --- a/internal/cli/tracker.go +++ b/internal/cli/tracker.go @@ -23,9 +23,9 @@ import ( "fmt" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) type PendingRequest struct { diff --git a/pkg/cfg/cfg.go b/pkg/cfg/cfg.go index fb2eb5f1..fdaeca59 100644 --- a/pkg/cfg/cfg.go +++ b/pkg/cfg/cfg.go @@ -29,7 +29,7 @@ import ( "github.com/BurntSushi/toml" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type ( diff --git a/pkg/client/clientimpl.go b/pkg/client/clientimpl.go index 0648fd65..7ab57804 100644 --- a/pkg/client/clientimpl.go +++ b/pkg/client/clientimpl.go @@ -17,20 +17,22 @@ // limitations under the License. // +// Package client provides interfaces and implementations for communicating with a Juno server. package client import ( "fmt" "runtime" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/internal/cli" - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/proto" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" ) +// clientImplT is the default implementation of the IClient interface. type clientImplT struct { config Config appName string @@ -38,6 +40,7 @@ type clientImplT struct { processor *cli.Processor } +// newProcessorWithConfig initializes a new Processor with the given configuration. func newProcessorWithConfig(conf *Config) *cli.Processor { if conf == nil { return nil @@ -51,6 +54,7 @@ func newProcessorWithConfig(conf *Config) *cli.Processor { return c } +// New initializes a new IClient with the given configuration. Returns an error if configuration validation fails. func New(conf Config) (IClient, error) { if err := conf.validate(); err != nil { return nil, err @@ -68,6 +72,7 @@ func New(conf Config) (IClient, error) { return client, nil } +// NewClient initializes a new IClient with the provided server address, namespace and app name. func NewClient(server string, ns string, app string) (IClient, error) { c := &clientImplT{ config: Config{ @@ -99,6 +104,8 @@ func NewClient(server string, ns string, app string) (IClient, error) { } ///TODO to revisit + +// Close closes the client and cleans up resources. func (c *clientImplT) Close() { if c.processor != nil { c.processor.Close() @@ -106,6 +113,7 @@ func (c *clientImplT) Close() { } } +// getOptions collects all provided options into an optionData object. func (c *clientImplT) getOptions(opts ...IOption) *optionData { data := &optionData{} for _, op := range opts { @@ -114,12 +122,14 @@ func (c *clientImplT) getOptions(opts ...IOption) *optionData { return data } +// newContext creates a new context from the provided operational message. func newContext(resp *proto.OperationalMessage) IContext { recInfo := &cli.RecordInfo{} recInfo.SetFromOpMsg(resp) return recInfo } +// Create sends a Create operation request to the server. func (c *clientImplT) Create(key []byte, value []byte, opts ...IOption) (context IContext, err error) { glog.Verbosef("Create ") var resp *proto.OperationalMessage @@ -138,6 +148,7 @@ func (c *clientImplT) Create(key []byte, value []byte, opts ...IOption) (context return } +// Get sends a Get operation request to the server. func (c *clientImplT) Get(key []byte, opts ...IOption) (value []byte, context IContext, err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -161,6 +172,7 @@ func (c *clientImplT) Get(key []byte, opts ...IOption) (value []byte, context IC return } +// Update sends an Update operation request to the server. func (c *clientImplT) Update(key []byte, value []byte, opts ...IOption) (context IContext, err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -183,6 +195,7 @@ func (c *clientImplT) Update(key []byte, value []byte, opts ...IOption) (context return } +// Set sends a Set operation request to the server. func (c *clientImplT) Set(key []byte, value []byte, opts ...IOption) (context IContext, err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -200,6 +213,7 @@ func (c *clientImplT) Set(key []byte, value []byte, opts ...IOption) (context IC return } +// Destroy sends a Destroy operation request to the server. func (c *clientImplT) Destroy(key []byte, opts ...IOption) (err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -215,6 +229,7 @@ func (c *clientImplT) Destroy(key []byte, opts ...IOption) (err error) { return } +// UDFGet sends a UDFGet operation request to the server. func (c *clientImplT) UDFGet(key []byte, fname []byte, params []byte, opts ...IOption) (value []byte, context IContext, err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -239,6 +254,7 @@ func (c *clientImplT) UDFGet(key []byte, fname []byte, params []byte, opts ...IO return } +// UDFSet sends a UDFSet operation request to the server. func (c *clientImplT) UDFSet(key []byte, fname []byte, params []byte, opts ...IOption) (context IContext, err error) { var resp *proto.OperationalMessage options := newOptionData(opts...) @@ -258,10 +274,13 @@ func (c *clientImplT) UDFSet(key []byte, fname []byte, params []byte, opts ...IO } ///TODO temporary + +// Batch sends a batch of operation requests to the server. func (c *clientImplT) Batch(requests []*proto.OperationalMessage) (responses []*proto.OperationalMessage, err error) { return c.processor.ProcessBatchRequests(requests) } +// NewRequest creates a new OperationalMessage with the provided parameters. func (c *clientImplT) NewRequest(op proto.OpCode, key []byte, value []byte, ttl uint32) (request *proto.OperationalMessage) { ///TODO: validate op request = &proto.OperationalMessage{} @@ -272,6 +291,7 @@ func (c *clientImplT) NewRequest(op proto.OpCode, key []byte, value []byte, ttl return } +// NewUDFRequest creates a new UDF OperationalMessage with the provided parameters. func (c *clientImplT) NewUDFRequest(op proto.OpCode, key []byte, fname []byte, params []byte, ttl uint32) (request *proto.OperationalMessage) { ///TODO: validate op request = &proto.OperationalMessage{} @@ -284,6 +304,7 @@ func (c *clientImplT) NewUDFRequest(op proto.OpCode, key []byte, fname []byte, p return } +// checkResponse validates the response from the server against the original request. func checkResponse(request *proto.OperationalMessage, response *proto.OperationalMessage, recInfo *cli.RecordInfo) (err error) { opCode := request.GetOpCode() if opCode != response.GetOpCode() { diff --git a/pkg/client/config.go b/pkg/client/config.go index 22a4d90e..860cf076 100644 --- a/pkg/client/config.go +++ b/pkg/client/config.go @@ -1,47 +1,49 @@ +// Copyright 2023 PayPal Inc. // -// Copyright 2023 PayPal Inc. -// -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// Package client handles the configuration for a Juno client. package client import ( "fmt" "time" - "juno/pkg/io" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" ) +// Duration is a type alias for util.Duration. type Duration = util.Duration +// Config holds the configuration values for the Juno client. type Config struct { - Server io.ServiceEndpoint - Appname string - Namespace string - RetryCount int - DefaultTimeToLive int - ConnectTimeout Duration - ReadTimeout Duration - WriteTimeout Duration - RequestTimeout Duration - ConnRecycleTimeout Duration + Server io.ServiceEndpoint // Server defines the ServiceEndpoint of the Juno server. + Appname string // Appname is the name of the application. + Namespace string // Namespace is the namespace of the application. + RetryCount int // RetryCount is the maximum number of retries. + DefaultTimeToLive int // DefaultTimeToLive is the default TTL (time to live) for requests. + ConnectTimeout Duration // ConnectTimeout is the timeout for establishing connections. + ReadTimeout Duration // ReadTimeout is the timeout for read operations. + WriteTimeout Duration // WriteTimeout is the timeout for write operations. + RequestTimeout Duration // RequestTimeout is the timeout for each request. + ConnRecycleTimeout Duration // ConnRecycleTimeout is the timeout for connection recycling. } +// defaultConfig defines the default configuration values. var defaultConfig = Config{ RetryCount: 1, DefaultTimeToLive: 1800, @@ -52,10 +54,12 @@ var defaultConfig = Config{ ConnRecycleTimeout: Duration{9 * time.Second}, } +// SetDefaultTimeToLive sets the default time to live (TTL) for the configuration. func SetDefaultTimeToLive(ttl int) { defaultConfig.DefaultTimeToLive = ttl } +// SetDefaultTimeout sets the default timeout durations for the configuration. func SetDefaultTimeout(connect, read, write, request, connRecycle time.Duration) { defaultConfig.ConnectTimeout.Duration = connect defaultConfig.ReadTimeout.Duration = read @@ -64,10 +68,14 @@ func SetDefaultTimeout(connect, read, write, request, connRecycle time.Duration) defaultConfig.ConnRecycleTimeout.Duration = connRecycle } +// SetDefault updates the current Config to match the default Config. func (c *Config) SetDefault() { *c = defaultConfig } +// validate checks if the required fields of the Config are correctly populated. +// It validates the Server field and checks if Appname and Namespace are specified. +// It returns an error if any of the above conditions are not met. func (c *Config) validate() error { if err := c.Server.Validate(); err != nil { return err @@ -78,6 +86,6 @@ func (c *Config) validate() error { if len(c.Namespace) == 0 { return fmt.Errorf("Config.Namespace not specified.") } - /// TODO to validate others + // TODO to validate others return nil } diff --git a/pkg/client/error.go b/pkg/client/error.go index 18c7332b..5dd6991f 100644 --- a/pkg/client/error.go +++ b/pkg/client/error.go @@ -17,61 +17,66 @@ // limitations under the License. // +// client is a package that handles various error situations in the Juno application. package client import ( - "juno/internal/cli" - "juno/pkg/proto" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/proto" ) +// Error variables for different scenarios in the application. var ( - ErrNoKey error - ErrUniqueKeyViolation error - ErrBadParam error - ErrConditionViolation error + ErrNoKey error // Error when no key is found. + ErrUniqueKeyViolation error // Error when there is a violation of a unique key. + ErrBadParam error // Error when a bad parameter is provided. + ErrConditionViolation error // Error when a condition violation occurs. - ErrBadMsg error - ErrNoStorage error - ErrRecordLocked error - ErrTTLExtendFailure error - ErrBusy error + ErrBadMsg error // Error when a bad message is encountered. + ErrNoStorage error // Error when no storage is available. + ErrRecordLocked error // Error when a record is locked. + ErrTTLExtendFailure error // Error when TTL extension fails. + ErrBusy error // Error when the server is busy. - ErrWriteFailure error - ErrInternal error - ErrOpNotSupported error + ErrWriteFailure error // Error when a write operation fails. + ErrInternal error // Error when an internal problem occurs. + ErrOpNotSupported error // Error when the operation is not supported. ) +// errorMapping is a map between different operation status and their corresponding errors. var errorMapping map[proto.OpStatus]error +// init function initializes the error variables and the errorMapping map. func init() { - ErrNoKey = &cli.Error{"no key"} - ErrUniqueKeyViolation = &cli.Error{"unique key violation"} - ErrBadParam = &cli.Error{"bad parameter"} - ErrConditionViolation = &cli.Error{"condition violation"} //version too old - ErrTTLExtendFailure = &cli.Error{"fail to extend TTL"} + ErrNoKey = &cli.Error{"no key"} // Error when the key does not exist. + ErrUniqueKeyViolation = &cli.Error{"unique key violation"} // Error when unique key constraint is violated. + ErrBadParam = &cli.Error{"bad parameter"} // Error when a bad parameter is passed. + ErrConditionViolation = &cli.Error{"condition violation"} // Error when there is a condition violation. + ErrTTLExtendFailure = &cli.Error{"fail to extend TTL"} // Error when TTL extension fails. - ErrBadMsg = &cli.RetryableError{"bad message"} - ErrNoStorage = &cli.RetryableError{"no storage"} - ErrRecordLocked = &cli.RetryableError{"record locked"} - ErrBusy = &cli.RetryableError{"server busy"} + ErrBadMsg = &cli.RetryableError{"bad message"} // Error when an inappropriate message is received. + ErrNoStorage = &cli.RetryableError{"no storage"} // Error when there is no storage available. + ErrRecordLocked = &cli.RetryableError{"record locked"} // Error when a record is locked. + ErrBusy = &cli.RetryableError{"server busy"} // Error when the server is busy. - ErrWriteFailure = &cli.Error{"write failure"} - ErrInternal = &cli.Error{"internal error"} - ErrOpNotSupported = &cli.Error{"Op not supported"} + ErrWriteFailure = &cli.Error{"write failure"} // Error when a write operation fails. + ErrInternal = &cli.Error{"internal error"} // Error when an internal error occurs. + ErrOpNotSupported = &cli.Error{"Op not supported"} // Error when the operation is not supported. + // Mapping between the operation status and the corresponding errors. errorMapping = map[proto.OpStatus]error{ - proto.OpStatusNoError: nil, - proto.OpStatusInconsistent: nil, - proto.OpStatusBadMsg: ErrBadMsg, - proto.OpStatusNoKey: ErrNoKey, - proto.OpStatusDupKey: ErrUniqueKeyViolation, - proto.OpStatusNoStorageServer: ErrNoStorage, - proto.OpStatusBadParam: ErrBadParam, - proto.OpStatusRecordLocked: ErrRecordLocked, - proto.OpStatusVersionConflict: ErrConditionViolation, - proto.OpStatusSSReadTTLExtendErr: ErrTTLExtendFailure, - proto.OpStatusCommitFailure: ErrWriteFailure, - proto.OpStatusBusy: ErrBusy, - proto.OpStatusNotSupported: ErrOpNotSupported, + proto.OpStatusNoError: nil, // Status when there is no error. + proto.OpStatusInconsistent: nil, // Status when there is an inconsistency. + proto.OpStatusBadMsg: ErrBadMsg, // Status when a bad message is received. + proto.OpStatusNoKey: ErrNoKey, // Status when the key is not present. + proto.OpStatusDupKey: ErrUniqueKeyViolation, // Status when unique key constraint is violated. + proto.OpStatusNoStorageServer: ErrNoStorage, // Status when there is no storage server available. + proto.OpStatusBadParam: ErrBadParam, // Status when a bad parameter is passed. + proto.OpStatusRecordLocked: ErrRecordLocked, // Status when a record is locked. + proto.OpStatusVersionConflict: ErrConditionViolation, // Status when there is a version conflict. + proto.OpStatusSSReadTTLExtendErr: ErrTTLExtendFailure, // Status when TTL extension fails. + proto.OpStatusCommitFailure: ErrWriteFailure, // Status when a commit operation fails. + proto.OpStatusBusy: ErrBusy, // Status when the server is busy. + proto.OpStatusNotSupported: ErrOpNotSupported, // Status when the operation is not supported. } } diff --git a/pkg/client/example_test.go b/pkg/client/example_test.go index ebb7a991..2e1a8985 100644 --- a/pkg/client/example_test.go +++ b/pkg/client/example_test.go @@ -22,7 +22,7 @@ package client_test import ( "fmt" - "juno/pkg/client" + "github.com/paypal/junodb/pkg/client" ) func Example_config() { diff --git a/pkg/client/option.go b/pkg/client/option.go index 849400b2..2e77f42c 100644 --- a/pkg/client/option.go +++ b/pkg/client/option.go @@ -17,16 +17,19 @@ // limitations under the License. // +// Package client provides functionalities for client configurations. package client import () +// optionData struct contains client options. type optionData struct { - ttl uint32 - context IContext - correlationId string + ttl uint32 // Time to live value. + context IContext // Client context. + correlationId string // Correlation ID for tracking. } +// IOption type represents a function that applies options on optionData. //type IOption interface { // Apply(data *optionData) error //} @@ -46,34 +49,41 @@ type optionData struct { type IOption func(data interface{}) +// WithTTL function returns an IOption that sets a TTL value. func WithTTL(ttl uint32) IOption { return func(i interface{}) { + // Check if the passed interface can be casted to *optionData if data, ok := i.(*optionData); ok { - data.ttl = ttl + data.ttl = ttl // Set the TTL value. } } } +// WithCond function returns an IOption that sets a context. func WithCond(context IContext) IOption { return func(i interface{}) { + // Check if the passed interface can be casted to *optionData if data, ok := i.(*optionData); ok { - data.context = context + data.context = context // Set the context. } } } +// WithCorrelationId function returns an IOption that sets a correlationId. func WithCorrelationId(id string) IOption { return func(i interface{}) { + // Check if the passed interface can be casted to *optionData if data, ok := i.(*optionData); ok { - data.correlationId = id + data.correlationId = id // Set the correlation ID. } } } +// newOptionData function applies the options passed in and returns an initialized optionData. func newOptionData(opts ...IOption) *optionData { - data := &optionData{} + data := &optionData{} // Initialize a new optionData. for _, op := range opts { - op(data) + op(data) // Apply each option on the optionData. } - return data + return data // Return the initialized optionData. } diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 3b0827d7..57087fbe 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -32,7 +32,7 @@ import ( "syscall" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" ) diff --git a/pkg/cluster/clusterstats.go b/pkg/cluster/clusterstats.go index 804c5134..058c4209 100644 --- a/pkg/cluster/clusterstats.go +++ b/pkg/cluster/clusterstats.go @@ -21,11 +21,13 @@ package cluster import ( "fmt" + "strings" "sync" "time" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging/otel" - "juno/pkg/util" - "juno/third_party/forked/golang/glog" ) type ProcStat struct { @@ -180,6 +182,8 @@ func (c *ClusterStats) processStateChange(st *ProcStat) { c.MarkdownTable[idx] = true glog.Infof("markdown: node %d-%d, exp:%d, timout ct: %d", st.zoneid, st.nodeid, c.MarkdownExpiration[idx], timeoutCnt) + targetSS := getIP(st.zoneid, st.nodeid) + otel.RecordCount(otel.SoftMark, []otel.Tags{{otel.Target, targetSS}, {otel.Status, otel.SSMarkDown}}) } } @@ -194,6 +198,20 @@ func (c *ClusterStats) processStateChange(st *ProcStat) { } } +func getIP(zoneid uint32, nodeid uint32) string { + shardMgr := GetShardMgr() + // First check if the connInfo has the element. + if len(shardMgr.connInfo) < int(zoneid+1) || len(shardMgr.connInfo[zoneid]) < int(nodeid+1) { + return "" + } + i := strings.Index(shardMgr.connInfo[zoneid][nodeid], ":") + + if i < 0 { + return shardMgr.connInfo[zoneid][nodeid] + } + return shardMgr.connInfo[zoneid][nodeid][:i] +} + // Naive way of doing markup: markdown expired. // Potentially can add probe logic so that we markup only if it's in good state. func (c *ClusterStats) markup() { @@ -215,6 +233,8 @@ func (c *ClusterStats) markup() { glog.Infof("markup: host %d-%d", i, j) c.MarkdownExpiration[idx] = 0 c.MarkdownTable[idx] = false + targetSS := getIP(i, j) + otel.RecordCount(otel.SoftMark, []otel.Tags{{otel.Target, targetSS}, {otel.Status, otel.SSMarkUp}}) } } } diff --git a/pkg/cluster/lock_linux.go b/pkg/cluster/lock_linux.go index e9188f3d..2c541515 100644 --- a/pkg/cluster/lock_linux.go +++ b/pkg/cluster/lock_linux.go @@ -20,8 +20,9 @@ package cluster import ( - "juno/third_party/forked/golang/glog" "syscall" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func lockFile(fd int, mode int) bool { diff --git a/pkg/cluster/node.go b/pkg/cluster/node.go index 5451ce86..d9ed0c6c 100644 --- a/pkg/cluster/node.go +++ b/pkg/cluster/node.go @@ -26,7 +26,7 @@ import ( "strconv" "strings" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // Node class represent a logic node diff --git a/pkg/cluster/shardmgr.go b/pkg/cluster/shardmgr.go index 1d578316..78fa381b 100644 --- a/pkg/cluster/shardmgr.go +++ b/pkg/cluster/shardmgr.go @@ -28,14 +28,14 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - - "juno/pkg/io" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/shard" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/util" ) var ( @@ -338,8 +338,8 @@ func (p *ShardManager) GetSSProcessor(zoneId int, nodeId int) *OutboundSSProcess return p.processors[zoneId][nodeId] } -//used by request processor -//the caller's responsibility to make sure +// used by request processor +// the caller's responsibility to make sure // cap(procs) >= numZones and cap(pos) >= numZones func (p *ShardManager) GetSSProcessors(key []byte, confNumWrites int, procs []*OutboundSSProcessor, pos []int) (shardId shard.ID, numProcs int) { @@ -759,9 +759,9 @@ func (p *OutboundSSProcessor) GetNodeInfo() (zoneid int, hostid int) { } func (p *OutboundSSProcessor) OnConnectSuccess(conn io.Conn, connector *io.OutboundConnector, timeTaken time.Duration) { + netConn := conn.GetNetConn() if cal.IsEnabled() { b := logging.NewKVBuffer() - netConn := conn.GetNetConn() b.Add([]byte("raddr"), netConn.RemoteAddr().String()) b.Add([]byte("laddr"), netConn.LocalAddr().String()) @@ -771,10 +771,9 @@ func (p *OutboundSSProcessor) OnConnectSuccess(conn io.Conn, connector *io.Outbo cal.AtomicTransaction(logging.CalMsgTypeSSConnect, p.Name(), cal.StatusSuccess, timeTaken, b.Bytes()) } - if otel.IsEnabled() { - netConn := conn.GetNetConn() - otel.RecordSSConnection(netConn.RemoteAddr().String(), otel.StatusSuccess, timeTaken.Milliseconds()) - } + + otel.RecordSSConnection(getIPAddress(netConn.RemoteAddr().String()), otel.StatusSuccess, timeTaken.Microseconds()) + } func (p *OutboundSSProcessor) OnConnectError(timeTaken time.Duration, connStr string, err error) { @@ -784,9 +783,14 @@ func (p *OutboundSSProcessor) OnConnectError(timeTaken time.Duration, connStr st b.Add([]byte("err"), err.Error()) cal.AtomicTransaction(logging.CalMsgTypeSSConnectError, p.Name(), cal.StatusSuccess, timeTaken, b.Bytes()) } - if otel.IsEnabled() { - otel.RecordSSConnection(connStr, otel.StatusError, timeTaken.Milliseconds()) - } + + otel.RecordSSConnection(getIPAddress(connStr), otel.StatusError, timeTaken.Microseconds()) + +} + +func getIPAddress(endpoint string) string { + s := strings.Split(endpoint, ":") + return s[0] } func (m *ZoneMarkDown) MarkDown(zoneid int32) { diff --git a/pkg/cluster/util.go b/pkg/cluster/util.go index 50f3220d..50c9f0cb 100644 --- a/pkg/cluster/util.go +++ b/pkg/cluster/util.go @@ -22,7 +22,7 @@ package cluster import ( "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func DisplayZones(zones []*Zone, header string) { diff --git a/pkg/cluster/zone.go b/pkg/cluster/zone.go index 0de13647..7fa97aca 100644 --- a/pkg/cluster/zone.go +++ b/pkg/cluster/zone.go @@ -23,7 +23,7 @@ import ( "fmt" "sort" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // Node class represent a logic node diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 2859cb76..aa405968 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -30,9 +30,9 @@ import ( "strings" "text/tabwriter" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/version" ) var ( diff --git a/pkg/etcd/config.go b/pkg/etcd/config.go index a89f4c62..0aea1c02 100644 --- a/pkg/etcd/config.go +++ b/pkg/etcd/config.go @@ -24,7 +24,7 @@ import ( clientv3 "go.etcd.io/etcd/client/v3" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/pkg/etcd/etcd.go b/pkg/etcd/etcd.go index 8fdd8d19..65e0d1d6 100644 --- a/pkg/etcd/etcd.go +++ b/pkg/etcd/etcd.go @@ -21,8 +21,9 @@ package etcd import ( "errors" - "juno/third_party/forked/golang/glog" "sync" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/pkg/etcd/etcdclient.go b/pkg/etcd/etcdclient.go index 770c7de2..26c873b4 100644 --- a/pkg/etcd/etcdclient.go +++ b/pkg/etcd/etcdclient.go @@ -32,7 +32,7 @@ import ( clientv3 "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/client/v3/namespace" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/pkg/etcd/etcdreader.go b/pkg/etcd/etcdreader.go index 00cead95..93bb0db9 100644 --- a/pkg/etcd/etcdreader.go +++ b/pkg/etcd/etcdreader.go @@ -28,11 +28,11 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cluster" - "juno/pkg/shard" - "juno/pkg/stats/redist" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/shard" + "github.com/paypal/junodb/pkg/stats/redist" ) // Implements cluster.IReader diff --git a/pkg/etcd/etcdwriter.go b/pkg/etcd/etcdwriter.go index 5bf10b10..d9a963c2 100644 --- a/pkg/etcd/etcdwriter.go +++ b/pkg/etcd/etcdwriter.go @@ -25,9 +25,9 @@ import ( "strconv" "strings" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/cluster" + "github.com/paypal/junodb/pkg/cluster" ) type IKVWriter interface { diff --git a/pkg/initmgr/init.go b/pkg/initmgr/init.go index 01092d9b..1818b276 100644 --- a/pkg/initmgr/init.go +++ b/pkg/initmgr/init.go @@ -32,8 +32,8 @@ import ( "syscall" "time" - "juno/pkg/logging" - "juno/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" ) var ( diff --git a/pkg/io/conn.go b/pkg/io/conn.go index 226810f8..e5f98eb3 100644 --- a/pkg/io/conn.go +++ b/pkg/io/conn.go @@ -24,16 +24,19 @@ import ( "net" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/sec" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/sec" ) type Conn interface { GetStateString() string + GetTLSVersion() string + GetCipherName() string + DidResume() string GetNetConn() net.Conn IsTLS() bool } @@ -51,6 +54,17 @@ func (c *Connection) GetStateString() string { return "" } +func (c *Connection) GetTLSVersion() string { + return "" +} + +func (c *Connection) GetCipherName() string { + return "" +} + +func (c *Connection) DidResume() string { + return "" +} func (c *Connection) GetNetConn() net.Conn { return c.conn } @@ -91,13 +105,15 @@ func Connect(endpoint *ServiceEndpoint, connectTimeout time.Duration) (conn net. cal.AtomicTransaction(cal.TxnTypeConnect, endpoint.Addr, status, time.Since(timeStart), b.Bytes()) } } - if otel.IsEnabled() { - status := otel.StatusSuccess - if err != nil { - status = otel.StatusError - } - otel.RecordOutboundConnection(endpoint.Addr, status, time.Since(timeStart).Milliseconds()) + status := otel.StatusSuccess + + if err != nil { + status = otel.StatusError + } else { + otel.RecordCount(otel.TLSStatus, []otel.Tags{{otel.Endpoint, endpoint.Addr}, {otel.TLS_version, sslconn.GetTLSVersion()}, + {otel.Cipher, sslconn.GetCipherName()}, {otel.Ssl_r, sslconn.DidResume()}}) } + otel.RecordOutboundConnection(endpoint.Addr, status, time.Since(timeStart).Microseconds()) } else { if conn, err = net.DialTimeout("tcp", endpoint.Addr, connectTimeout); err == nil { if glog.LOG_DEBUG { @@ -115,13 +131,11 @@ func Connect(endpoint *ServiceEndpoint, connectTimeout time.Duration) (conn net. } cal.AtomicTransaction(cal.TxnTypeConnect, endpoint.GetConnString(), status, time.Since(timeStart), data) } - if otel.IsEnabled() { - status := otel.StatusSuccess - if err != nil { - status = otel.StatusError - } - otel.RecordOutboundConnection(endpoint.GetConnString(), status, time.Since(timeStart).Milliseconds()) + status := otel.StatusSuccess + if err != nil { + status = otel.StatusError } + otel.RecordOutboundConnection(endpoint.GetConnString(), status, time.Since(timeStart).Microseconds()) } return diff --git a/pkg/io/connmgr.go b/pkg/io/connmgr.go index f44f1c6a..c2250841 100644 --- a/pkg/io/connmgr.go +++ b/pkg/io/connmgr.go @@ -23,7 +23,7 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type InboundConnManager struct { diff --git a/pkg/io/inboundconnector.go b/pkg/io/inboundconnector.go index bfc8a862..bc477cd0 100644 --- a/pkg/io/inboundconnector.go +++ b/pkg/io/inboundconnector.go @@ -29,13 +29,13 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - - "juno/pkg/debug" - "juno/pkg/io/ioutil" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/io/ioutil" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/pkg/logging/otel" ) type Connector struct { @@ -83,6 +83,7 @@ func (c *Connector) Close() { cal.Event(cal.TxnTypeClose, rhost, cal.StatusSuccess, []byte(addr)) } } + otel.RecordCount(otel.Close, []otel.Tags{}) c.cancelCtx() }) } diff --git a/pkg/io/ioconfig.go b/pkg/io/ioconfig.go index 107b8253..6aae8148 100644 --- a/pkg/io/ioconfig.go +++ b/pkg/io/ioconfig.go @@ -22,7 +22,7 @@ package io import ( "time" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/pkg/io/ioutil/logerr.go b/pkg/io/ioutil/logerr.go index 5af8f8f5..63568e48 100644 --- a/pkg/io/ioutil/logerr.go +++ b/pkg/io/ioutil/logerr.go @@ -25,7 +25,7 @@ import ( "os" "syscall" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func LogError(err error) { diff --git a/pkg/io/listener.go b/pkg/io/listener.go index c93f3fba..ae43d305 100644 --- a/pkg/io/listener.go +++ b/pkg/io/listener.go @@ -25,10 +25,10 @@ import ( "os" "time" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/util" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) const ( @@ -148,10 +148,10 @@ func (l *Listener) AcceptAndServe() error { cal.Event(cal.TxnTypeAccept, rhost, cal.StatusSuccess, []byte("raddr="+raddr+"&laddr="+conn.LocalAddr().String())) } } - if otel.IsEnabled() { - otel.RecordCount(otel.Accept, nil) - } + otel.RecordCount(otel.Accept, []otel.Tags{{otel.Status, otel.Success}}) l.startNewConnector(conn) + } else { + otel.RecordCount(otel.Accept, []otel.Tags{{otel.Status, otel.Error}}) } //log the error in caller if needed return err diff --git a/pkg/io/mayflyreqctx.go b/pkg/io/mayflyreqctx.go index 8cf0a1f7..386896f9 100644 --- a/pkg/io/mayflyreqctx.go +++ b/pkg/io/mayflyreqctx.go @@ -26,13 +26,13 @@ import ( "io" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/pkg/io/outboundconnector.go b/pkg/io/outboundconnector.go index db737560..5449405d 100644 --- a/pkg/io/outboundconnector.go +++ b/pkg/io/outboundconnector.go @@ -31,13 +31,13 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/io/ioutil" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io/ioutil" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) const ( diff --git a/pkg/io/outboundprocessor.go b/pkg/io/outboundprocessor.go index 48fcbf28..102299a1 100644 --- a/pkg/io/outboundprocessor.go +++ b/pkg/io/outboundprocessor.go @@ -28,14 +28,14 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" - - "juno/pkg/errors" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/logging/otel" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/pkg/errors" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/otel" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type ( @@ -114,9 +114,7 @@ func (p *OutboundProcessor) GetRequestCh() chan IRequestContext { return p.reqCh } -// // Non-blocking send -// func (p *OutboundProcessor) sendRequest(req IRequestContext) (err *errors.Error) { // send request select { @@ -314,18 +312,16 @@ func (p *OutboundProcessor) OnConnectSuccess(conn Conn, connector *OutboundConne cal.AtomicTransaction(cal.TxnTypeConnect, p.connInfo.GetConnString(), cal.StatusSuccess, timeTaken, data) } - if otel.IsEnabled() { - otel.RecordOutboundConnection(p.connInfo.GetConnString(), otel.StatusSuccess, timeTaken.Milliseconds()) - } + otel.RecordOutboundConnection(p.connInfo.GetConnString(), otel.StatusSuccess, timeTaken.Microseconds()) + otel.RecordCount(otel.TLSStatus, []otel.Tags{{otel.Endpoint, p.connInfo.GetConnString()}, {otel.TLS_version, conn.GetTLSVersion()}, + {otel.Cipher, conn.GetCipherName()}, {otel.Ssl_r, conn.DidResume()}}) } func (p *OutboundProcessor) OnConnectError(timeTaken time.Duration, connStr string, err error) { if cal.IsEnabled() { cal.AtomicTransaction(cal.TxnTypeConnect, connStr, cal.StatusError, timeTaken, []byte(err.Error())) } - if otel.IsEnabled() { - otel.RecordOutboundConnection(connStr, otel.StatusError, timeTaken.Milliseconds()) - } + otel.RecordOutboundConnection(connStr, otel.StatusError, timeTaken.Microseconds()) } func (p *OutboundProcessor) connect(connCh chan *OutboundConnector, id int, connector *OutboundConnector) { diff --git a/pkg/io/requestcontext.go b/pkg/io/requestcontext.go index 25c06f24..96cf9cd5 100644 --- a/pkg/io/requestcontext.go +++ b/pkg/io/requestcontext.go @@ -26,11 +26,11 @@ import ( "io" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/proto" - "juno/pkg/proto/mayfly" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/proto/mayfly" + "github.com/paypal/junodb/pkg/util" ) var oResponsePool = util.NewChanPool(10000, func() interface{} { diff --git a/pkg/io/ssllistener.go b/pkg/io/ssllistener.go index db623292..157411fc 100644 --- a/pkg/io/ssllistener.go +++ b/pkg/io/ssllistener.go @@ -26,11 +26,11 @@ import ( "syscall" "time" - "juno/third_party/forked/golang/glog" - - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/sec" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/logging/otel" ) type SslListener struct { @@ -66,6 +66,8 @@ func (l *SslListener) AcceptAndServe() error { cal.Event(cal.TxnTypeAccept, rhost, cal.StatusSuccess, b.Bytes()) } } + otel.RecordCount(otel.Accept, []otel.Tags{{otel.Status, otel.Success}, {otel.TLS_version, sslConn.GetTLSVersion()}, + {otel.Cipher, sslConn.GetCipherName()}, {otel.Ssl_r, sslConn.DidResume()}}) l.startNewConnector(sslConn.GetNetConn()) } else { logAsWarning := true @@ -95,6 +97,15 @@ func (l *SslListener) AcceptAndServe() error { cal.Event(cal.TxnTypeAccept, rhost, st, b.Bytes()) } } + + otelStatus := otel.Success + if logAsWarning { + otelStatus = otel.Warn + } + + otel.RecordCount(otel.Accept, []otel.Tags{{otel.Status, otelStatus}, {otel.TLS_version, sslConn.GetTLSVersion()}, + {otel.Cipher, sslConn.GetCipherName()}, {otel.Ssl_r, sslConn.DidResume()}}) + if logAsWarning { glog.Warning("handshaking error: ", err) } else { diff --git a/pkg/logging/cal/config/calconfig.go b/pkg/logging/cal/config/calconfig.go index 993c8471..12cf3dc0 100644 --- a/pkg/logging/cal/config/calconfig.go +++ b/pkg/logging/cal/config/calconfig.go @@ -20,7 +20,7 @@ package config import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var CalConfig *Config diff --git a/pkg/logging/cal/logger.go b/pkg/logging/cal/logger.go index d0a8b4a6..dcd6cb49 100644 --- a/pkg/logging/cal/logger.go +++ b/pkg/logging/cal/logger.go @@ -27,11 +27,11 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging/cal/config" - "juno/pkg/logging/cal/net/io" - "juno/pkg/logging/cal/net/protocol" + "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/logging/cal/net/io" + "github.com/paypal/junodb/pkg/logging/cal/net/protocol" ) // CAL message Status field values @@ -126,7 +126,7 @@ func LogAtomicTransaction(txnType, eventName, status string, duration time.Durat client.Send(msg) } -//SendEvent logs an event of eventType with a sub-classification of +// SendEvent logs an event of eventType with a sub-classification of // eventName. The event may optionally contain extra eventData. func LogEvent(eventType, eventName, status string, eventData map[string]interface{}) { // TODO guard against bad eventType/eventName (perhaps in NewMsg()) diff --git a/pkg/logging/cal/net/io/client.go b/pkg/logging/cal/net/io/client.go index a735200e..38137347 100644 --- a/pkg/logging/cal/net/io/client.go +++ b/pkg/logging/cal/net/io/client.go @@ -32,11 +32,11 @@ import ( "sync/atomic" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging/cal/config" - "juno/pkg/logging/cal/net/protocol" - "juno/pkg/logging/cal/util" + "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/logging/cal/net/protocol" + "github.com/paypal/junodb/pkg/logging/cal/util" ) var logFile *os.File @@ -259,9 +259,7 @@ func (c *client) sendFileLoop() { } } -// // Sender need to make should not send message after Shutdown() -// func (c *client) Send(m *protocol.CalMessage) { if m == nil { glog.V(2).Info("Cal: Message can not be nil.") @@ -282,7 +280,7 @@ func (c *client) Send(m *protocol.CalMessage) { } } -//If you close client connection you wouldnt be able to log anything using logger. +// If you close client connection you wouldnt be able to log anything using logger. // This should be called when parent process Shutdown. func (c *client) Shutdown() { c.closeOnce.Do(func() { @@ -307,7 +305,7 @@ func (c *client) Shutdown() { }) } -//Flush blocks till the messages are processed by the channel +// Flush blocks till the messages are processed by the channel func (c *client) Flush() { c.wg.Wait() if logFile != nil { diff --git a/pkg/logging/cal/net/io/clientapi.go b/pkg/logging/cal/net/io/clientapi.go index fd0155ef..c9105393 100644 --- a/pkg/logging/cal/net/io/clientapi.go +++ b/pkg/logging/cal/net/io/clientapi.go @@ -21,10 +21,11 @@ package io import ( "bufio" - "juno/pkg/logging/cal/net/protocol" "net" "sync" "sync/atomic" + + "github.com/paypal/junodb/pkg/logging/cal/net/protocol" ) // Client is a CAL client. It is used to configure and organize diff --git a/pkg/logging/cal/net/protocol/message.go b/pkg/logging/cal/net/protocol/message.go index f096318c..1ebb2896 100644 --- a/pkg/logging/cal/net/protocol/message.go +++ b/pkg/logging/cal/net/protocol/message.go @@ -22,11 +22,12 @@ package protocol import ( "bytes" "fmt" - "juno/third_party/forked/golang/glog" "strconv" "strings" "time" "unicode" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // Msg is a single log message. diff --git a/pkg/logging/cal/test/main.go b/pkg/logging/cal/test/main.go index 9d107065..75b2e0fb 100644 --- a/pkg/logging/cal/test/main.go +++ b/pkg/logging/cal/test/main.go @@ -20,21 +20,21 @@ package main import ( - "juno/pkg/logging/cal" - logger "juno/pkg/logging/cal" - "juno/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/logging/cal" + logger "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/logging/cal/config" "github.com/BurntSushi/toml" - //"juno/pkg/logging/cal/config" + //"github.com/paypal/junodb/pkg/logging/cal/config" "flag" "fmt" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" //"io" // "log" - //"juno/pkg/logging/cal/net/protocol" + //"github.com/paypal/junodb/pkg/logging/cal/net/protocol" //"os" // "runtime" // "net/http" diff --git a/pkg/logging/cal/util/util.go b/pkg/logging/cal/util/util.go index c5760ea0..c2919beb 100644 --- a/pkg/logging/cal/util/util.go +++ b/pkg/logging/cal/util/util.go @@ -22,13 +22,14 @@ package util import ( "fmt" "hash/fnv" - "juno/pkg/logging/cal/net/protocol" "net" "os" "path" "runtime" "strconv" "time" + + "github.com/paypal/junodb/pkg/logging/cal/net/protocol" ) const ( diff --git a/pkg/logging/calstatus.go b/pkg/logging/calstatus.go index 8ff37d8a..4e89d1f7 100644 --- a/pkg/logging/calstatus.go +++ b/pkg/logging/calstatus.go @@ -20,8 +20,8 @@ package logging import ( - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) type Status int diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index 061cc7bd..b219aeec 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -26,11 +26,11 @@ import ( "strconv" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/logging/cal" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type KeyValueBuffer struct { @@ -360,7 +360,7 @@ func (b *KeyValueBuffer) AddOpRequestInfo(request *proto.OperationalMessage) *Ke return b } -//difference from AddOpRequestInfo(): namespace and key not logged +// difference from AddOpRequestInfo(): namespace and key not logged func (b *KeyValueBuffer) AddOpRequest(request *proto.OperationalMessage) *KeyValueBuffer { b.Add(logDataKeyRid, request.GetRequestIDString()) reqParam := &KeyValueBuffer{delimiter: ':', pairDelimiter: '|'} diff --git a/pkg/logging/otel/config/otelconfig.go b/pkg/logging/otel/config/otelconfig.go index 458dc90a..6f305c11 100644 --- a/pkg/logging/otel/config/otelconfig.go +++ b/pkg/logging/otel/config/otelconfig.go @@ -1,50 +1,54 @@ +// Copyright 2023 PayPal Inc. // -// Copyright 2023 PayPal Inc. +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at // -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// http://www.apache.org/licenses/LICENSE-2.0 // +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package config import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var OtelConfig *Config +type HistBuckets struct { + Replication []float64 + SsConnect []float64 + Inbound []float64 + OutboundConnection []float64 +} + type Config struct { - Host string - Port uint32 - Environment string - Poolname string - Enabled bool - Resolution uint32 - UseTls bool + Host string + Port uint32 + UrlPath string + Environment string + Poolname string + Enabled bool + Resolution uint32 + UseTls bool + HistogramBuckets HistBuckets } func (c *Config) Validate() { if len(c.Poolname) <= 0 { glog.Fatal("Error: Otel Poolname is required.") } + c.setDefaultIfNotDefined() } -func (c *Config) SetPoolName(name string) { - c.Poolname = name -} - -func (c *Config) Default() { +func (c *Config) setDefaultIfNotDefined() { if c.Host == "" { c.Host = "127.0.0.1" } @@ -55,7 +59,22 @@ func (c *Config) Default() { c.Resolution = 60 } if c.Environment == "" { - c.Environment = "OpenSource" + c.Environment = "PayPal" + } + if c.UrlPath == "" { + c.UrlPath = "v1/datapoint" + } + if c.HistogramBuckets.Inbound == nil { + c.HistogramBuckets.Inbound = []float64{200, 400, 800, 1200, 2400, 3600, 7200, 10800, 21600, 43200, 86400, 172800} + } + if c.HistogramBuckets.OutboundConnection == nil { + c.HistogramBuckets.OutboundConnection = []float64{200, 400, 800, 1200, 2400, 3600, 7200, 10800, 21600, 43200, 86400, 172800} + } + if c.HistogramBuckets.Replication == nil { + c.HistogramBuckets.Replication = []float64{200, 400, 800, 1200, 2400, 3600, 7200, 10800, 21600, 43200, 86400, 172800} + } + if c.HistogramBuckets.SsConnect == nil { + c.HistogramBuckets.SsConnect = []float64{100, 200, 300, 400, 800, 1200, 2400, 3600, 10800, 21600, 86400, 172800} } } @@ -65,5 +84,10 @@ func (c *Config) Dump() { glog.Infof("Environment: %s", c.Environment) glog.Infof("Poolname: %s", c.Poolname) glog.Infof("Resolution: %d", c.Resolution) - glog.Info("UseTls: %b", c.UseTls) + glog.Infof("UseTls: %t", c.UseTls) + glog.Infof("UrlPath: %s", c.UrlPath) + glog.Info("Inbound Bucket: ", c.HistogramBuckets.Inbound) + glog.Info("OutboundConnection Bucket: ", c.HistogramBuckets.OutboundConnection) + glog.Info("Replication Bucket: ", c.HistogramBuckets.Replication) + glog.Info("SsConnect Bucket: ", c.HistogramBuckets.SsConnect) } diff --git a/pkg/logging/otel/defs.go b/pkg/logging/otel/defs.go new file mode 100644 index 00000000..7421864b --- /dev/null +++ b/pkg/logging/otel/defs.go @@ -0,0 +1,267 @@ +// +// Copyright 2023 PayPal Inc. +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package otel + +import ( + "sync" + "time" + + instrument "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/sdk/metric" +) + +//*************************** Constants **************************** +const ( + RRDropMaxRetry CMetric = CMetric(iota) + RRDropQueueFull + RRDropRecExpired + SSL_CLIENT_INFO + CLIENT_INFO + Accept + Close + RAPI + ReqProc + ProcErr + SoftMark + TLSStatus + Inbound + Replication + OutboundConnection + SSConnection +) + +const ( + Target = string("target") + Endpoint = string("target_ip_port") + Operation = string("operation") + Client = string("client_app") + Status = string("status") + Fatal = string("Fatal") + Error = string("Error") + Warn = string("Warning") + Success = string("Success") + SS_RB_expire = string("SS_RB_expire") + SSReqTimeout = string("SSReqTimeout") + SSMarkDown = string("Down") + SSMarkUp = string("Up") + TLS_version = string("tls_version") + Cipher = string("cipher") + Ssl_r = string("ssl_r") +) + +const ( + SvrTypeProxy = ServerType(1) + SvrTypeStorage = ServerType(2) + SvrTypeClusterMgr = ServerType(3) + SvrTypeAll = ServerType(6) +) + +// OTEl Status +const ( + StatusSuccess string = "SUCCESS" + StatusFatal string = "FATAL" + StatusError string = "ERROR" + StatusWarning string = "WARNING" + StatusUnknown string = "UNKNOWN" +) + +const ( + MachineCpuUsed string = string("machineCpuUsed") + ProcessCpuUsed string = string("machineCpuUsed") + MachineMemoryUsed + ProcessMemoryUsed +) + +// default OTEL configurations point to QA collector +const DEFAULT_OTEL_COLLECTOR_PROTOCOL string = "http" +const DEFAULT_OTEL_COLLECTOR__IP string = "0.0.0.0" +const DEFAULT_GRPC_OTEL_COLLECTOR_PORT string = "4317" +const DEFAULT_HTTP_OTEL_COLLECTOR_PORT string = "4318" +const COLLECTOR_POLLING_INTERVAL_SECONDS int32 = 5 + +const JUNO_METRIC_PREFIX = "juno.server." +const MeterName = "juno-server-meter" +const histChannelSize = 1000 +const counterChannelSize = 1000 + +//****************************** variables *************************** + +var ( + apiHistogramOnce sync.Once + replicationHistogramOnce sync.Once + connectHistogramOnce sync.Once + ssConnectHistogramOnce sync.Once + rrDropMaxRetryCounterOnce sync.Once + rrDropQueueFullCounterOnce sync.Once + rrDropRecExpiredCounterOnce sync.Once + acceptCounterOnce sync.Once + closeCounterOnce sync.Once + rapiCounterOnce sync.Once + reqProcCounterOnce sync.Once + procErrCounterOnce sync.Once + softMarkCounterOnce sync.Once + tlsStatusCounterOnce sync.Once + sslClientInfoOnce sync.Once + clientInfoOnce sync.Once +) + +var apiHistogram instrument.Int64Histogram +var replicationHistogram instrument.Int64Histogram +var connectHistogram instrument.Int64Histogram +var ssConnectHistogram instrument.Int64Histogram + +var opsHistChannel chan DataPoint +var replHistChannel chan DataPoint +var ssConnHistChannel chan DataPoint +var outBoundHistChannel chan DataPoint +var counterChannel chan DataPoint + +var opsHistDoneCh chan bool +var replHistCh chan bool +var ssConnHistCh chan bool +var outBoundHistCh chan bool + +var countMetricMap map[CMetric]*countMetric = map[CMetric]*countMetric{ + RRDropMaxRetry: {"RR_Drop_MaxRetry", "Records dropped in replication queue due to max retry failures", nil, &rrDropMaxRetryCounterOnce, nil, nil}, + RRDropQueueFull: {"RR_Drop_QueueFull", "Records dropped in replication queue due to queue is full", nil, &rrDropQueueFullCounterOnce, nil, nil}, + RRDropRecExpired: {"RR_Drop_RecExpired", "Records dropped in replication queue due to expiry of records", nil, &rrDropRecExpiredCounterOnce, nil, nil}, + SSL_CLIENT_INFO: {"SSL_CLIENT_INFO", "Client app Info", nil, &sslClientInfoOnce, nil, nil}, + CLIENT_INFO: {"CLIENT_INFO", "Client app Info", nil, &clientInfoOnce, nil, nil}, + Accept: {"accept", "Accepting incoming connections", nil, &acceptCounterOnce, nil, nil}, + Close: {"close", "Closing incoming connections", nil, &closeCounterOnce, nil, nil}, + RAPI: {"rapi", "Processing of replicated requests", nil, &rapiCounterOnce, nil, nil}, + ReqProc: {"ReqProc", "Request processor", nil, &reqProcCounterOnce, nil, nil}, + ProcErr: {"ProcErr", "Request processor Error", nil, &procErrCounterOnce, nil, nil}, + SoftMark: {"SoftMark", "Proxy marks down storage instances", nil, &softMarkCounterOnce, nil, nil}, + TLSStatus: {"TLS_Status", "TLS connection state", nil, &tlsStatusCounterOnce, nil, nil}, +} + +var histMetricMap map[CMetric]*histogramMetric = map[CMetric]*histogramMetric{ + Inbound: {PopulateJunoMetricNamePrefix("inbound"), "Histogram for Juno API", "ms", nil, &apiHistogramOnce, nil, nil}, + Replication: {PopulateJunoMetricNamePrefix("replication"), "Histogram for Juno replication", "ms", nil, &replicationHistogramOnce, nil, nil}, + OutboundConnection: {PopulateJunoMetricNamePrefix("outbound_connection"), "Histogram for Juno connection", "us", nil, &connectHistogramOnce, nil, nil}, + SSConnection: {PopulateJunoMetricNamePrefix("ssConnection"), "Histogram for Juno SS connection", "us", nil, &ssConnectHistogramOnce, nil, nil}, +} + +var ( + meterProvider *metric.MeterProvider +) + +var ( + machineCpuUsedOnce sync.Once + processCpuUsedOnce sync.Once + machineMemoryUsedOnce sync.Once + processMemoryUsedOnce sync.Once + diskIOUtilization sync.Once + badShardOnce sync.Once + alertShardOnce sync.Once + warningShardOnce sync.Once + keyCountOnce sync.Once + freeStorageOnce sync.Once + usedStorageOnce sync.Once + LNLevelOnce sync.Once + compSecOnce sync.Once + compCountOnce sync.Once + pendingCompOnce sync.Once + stallOnce sync.Once + TCPConnCountOnce sync.Once + SSLConnCountOnce sync.Once +) + +var ( + machTime time.Time + machCpuTick uint16 + machUser uint64 + machSystem uint64 +) + +var GaugeMetricList = []*GaugeMetric{ + {"pCPU", "proc_cpu_used", "CPU utilization of individual Juno instance", nil, nil, &processCpuUsedOnce, SvrTypeAll}, + {"pMem", "proc_mem_used", "Memory utilization of individual Juno instance", nil, nil, &processMemoryUsedOnce, SvrTypeAll}, + + {"nBShd", "bad_shard", "Number of bad shards", nil, nil, &badShardOnce, SvrTypeProxy}, + {"nAShd", "alert_shard", "number of shards with no redundancy", nil, nil, &alertShardOnce, SvrTypeProxy}, + {"nWShd", "warning_shard", "number of shards with bad SS", nil, nil, &warningShardOnce, SvrTypeProxy}, + + {"conns", "conns_count", "number of current TCP connections", nil, nil, &TCPConnCountOnce, SvrTypeProxy}, + {"ssl_conns", "conns_ssl_count", "number of current SSL connections", nil, nil, &SSLConnCountOnce, SvrTypeProxy}, + {"keys", "key_count", "Key Counte in rocksDB", nil, nil, &keyCountOnce, SvrTypeStorage}, + {"free", "free_mb_storage_space", "Free Storage Space (mbytes)", nil, nil, &freeStorageOnce, SvrTypeStorage}, + {"used", "storage_used_mb", "Used Storage Space (mbytes)", nil, nil, &usedStorageOnce, SvrTypeStorage}, + {"LN", "LN_level", "Max LN Level in Rocksdb", nil, nil, &LNLevelOnce, SvrTypeStorage}, + {"compSec", "compaction_sec", "Compaction Sec", nil, nil, &compSecOnce, SvrTypeStorage}, + {"compCount", "compaction_count", "Compaction Count", nil, nil, &compCountOnce, SvrTypeStorage}, + {"pCompKB", "pending_compaction", "Pending Compaction KBytes", nil, nil, &pendingCompOnce, SvrTypeStorage}, + {"stall", "stall_write_rate", "Actural Delayed Write Rate", nil, nil, &stallOnce, SvrTypeStorage}, +} + +var otelIngestToken string + +// ************************************ Types **************************** +type CMetric int + +type Tags struct { + TagName string + TagValue string +} + +type countMetric struct { + metricName string + metricDesc string + counter instrument.Int64Counter + createCounter *sync.Once + counterCh chan DataPoint + doneCh chan bool +} + +type histogramMetric struct { + metricName string + metricDesc string + metricUnit string + histogram instrument.Int64Histogram + createHistogram *sync.Once + histogramCh chan DataPoint + doneCh chan bool +} + +type ( + ServerType int +) + +type GaugeMetric struct { + MetricShortName string + MetricName string + metricDesc string + gaugeMetric instrument.Float64ObservableGauge + stats []StateData + createGauge *sync.Once + stype ServerType +} + +// Represents stats by a worker +type StateData struct { + Name string + Value float64 + Dimensions instrument.MeasurementOption +} + +type DataPoint struct { + attr instrument.MeasurementOption + data int64 +} diff --git a/pkg/logging/otel/logger.go b/pkg/logging/otel/logger.go index 5559085e..e226be8b 100644 --- a/pkg/logging/otel/logger.go +++ b/pkg/logging/otel/logger.go @@ -1,156 +1,47 @@ +// Copyright 2023 PayPal Inc. // -// Copyright 2023 PayPal Inc. +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at // -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// http://www.apache.org/licenses/LICENSE-2.0 // +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package otel import ( - "bufio" "context" "errors" "fmt" - "io" "log" "os" - "strings" - "sync" + "time" - otelCfg "juno/pkg/logging/otel/config" - "juno/third_party/forked/golang/glog" + otelCfg "github.com/paypal/junodb/pkg/logging/otel/config" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" - "go.opentelemetry.io/otel/metric/global" - "go.opentelemetry.io/otel/metric/instrument" - "go.opentelemetry.io/otel/metric/instrument/syncint64" - "go.opentelemetry.io/otel/metric/unit" + instrument "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/aggregation" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" -) - -var ( - apiHistogramOnce sync.Once - replicationHistogramOnce sync.Once - connectHistogramOnce sync.Once - ssConnectHistogramOnce sync.Once - rrDropMaxRetryCounterOnce sync.Once - rrDropQueueFullCounterOnce sync.Once - rrDropRecExpiredCounterOnce sync.Once - acceptCounterOnce sync.Once - closeCounterOnce sync.Once - rapiCounterOnce sync.Once - reqProcCounterOnce sync.Once - procErrCounterOnce sync.Once -) - -var apiHistogram syncint64.Histogram -var replicationHistogram syncint64.Histogram -var connectHistogram syncint64.Histogram -var ssConnectHistogram syncint64.Histogram - -type CMetric int - -const ( - RRDropMaxRetry CMetric = CMetric(iota) - RRDropQueueFull - RRDropRecExpired - Accept - Close - RAPI - ReqProc - ProcErr -) - -type Tags struct { - TagName string - TagValue string -} - -const ( - Target = string("target") - Endpoint = string("endpoint") - Operation = string("operation") - Status = string("status") - Fatal = string("Fatal") - Error = string("Error") - Warn = string("Warning") - Success = string("Success") - SS_RB_expire = string("SS_RB_expire") - SSReqTimeout = string("SSReqTimeout") -) - -type countMetric struct { - metricName string - metricDesc string - counter syncint64.Counter - createCounter *sync.Once -} - -var countMetricMap map[CMetric]*countMetric = map[CMetric]*countMetric{ - RRDropMaxRetry: {"RR_Drop_MaxRetry", "Records dropped in replication queue due to max retry failures", nil, &rrDropMaxRetryCounterOnce}, - RRDropQueueFull: {"RR_Drop_QueueFull", "Records dropped in replication queue due to queue is full", nil, &rrDropQueueFullCounterOnce}, - RRDropRecExpired: {"RR_Drop_RecExpired", "Records dropped in replication queue due to expiry of records", nil, &rrDropRecExpiredCounterOnce}, - Accept: {"accept", "Accepting incoming connections", nil, &acceptCounterOnce}, - Close: {"close", "Closing incoming connections", nil, &closeCounterOnce}, - RAPI: {"rapi", "Processing of replicated requests", nil, &rapiCounterOnce}, - ReqProc: {"ReqProc", "Processing of replicated requests", nil, &reqProcCounterOnce}, - ProcErr: {"ProcErr", "Processing of replicated requests", nil, &procErrCounterOnce}, -} - -type ( - ServerType int -) - -const ( - SvrTypeProxy = ServerType(1) - SvrTypeStorage = ServerType(2) - SvrTypeClusterMgr = ServerType(3) - SvrTypeAll = ServerType(6) ) -// default OTEL configurations point to QA collector -var DEFAULT_OTEL_COLLECTOR_PROTOCOL string = "http" -var DEFAULT_GRPC_OTEL_COLLECTOR_PORT string = "30705" -var DEFAULT_HTTP_OTEL_COLLECTOR_PORT string = "30706" -var COLLECTOR_POLLING_INTERVAL_SECONDS int32 = 5 - -const JUNO_METRIC_PREFIX = "juno.server." -const MeterName = "juno-server-meter" - var OTEL_COLLECTOR_PROTOCOL string = DEFAULT_OTEL_COLLECTOR_PROTOCOL -// OTEl Status -const ( - StatusSuccess string = "SUCCESS" - StatusFatal string = "FATAL" - StatusError string = "ERROR" - StatusWarning string = "WARNING" - StatusUnknown string = "UNKNOWN" -) - -var ( - meterProvider *metric.MeterProvider -) - func Initialize(args ...interface{}) (err error) { glog.Info("Juno OTEL initialized") sz := len(args) @@ -166,6 +57,7 @@ func Initialize(args ...interface{}) (err error) { glog.Error(err) return } + c.Validate() c.Dump() if c.Enabled { // Initialize only if OTEL is enabled @@ -174,36 +66,84 @@ func Initialize(args ...interface{}) (err error) { return } +func Finalize() { + // Shutdown the Go routines for histograms + for _, val := range histMetricMap { + if val.histogram != nil && val.doneCh != nil { + close(val.doneCh) + } + } + + // Shutdown the Go routines for counters that are active + for _, val := range countMetricMap { + if val.counter != nil && val.doneCh != nil { + close(val.doneCh) + } + } +} + func InitMetricProvider(config *otelCfg.Config) { if meterProvider != nil { - fmt.Printf("Retrung as meter is already available") return } - //TODO Remove this after testing otelCfg.OtelConfig = config ctx := context.Background() - // View to customize histogram buckets and rename a single histogram instrument. repBucketsView := metric.NewView( metric.Instrument{ - Name: "*replication*", + Name: PopulateJunoMetricNamePrefix("replication"), Scope: instrumentation.Scope{Name: MeterName}, }, metric.Stream{ - Name: "replication", Aggregation: aggregation.ExplicitBucketHistogram{ - Boundaries: []float64{64, 128, 256, 512, 1024, 2048, 4096}, + Boundaries: config.HistogramBuckets.Replication, }, - }) + }, + ) + + ssConnBucketsView := metric.NewView( + metric.Instrument{ + Name: PopulateJunoMetricNamePrefix("ssConnection"), + Scope: instrumentation.Scope{Name: MeterName}, + }, + metric.Stream{ + Aggregation: aggregation.ExplicitBucketHistogram{ + Boundaries: config.HistogramBuckets.SsConnect, + }, + }, + ) + + inboundBucketsView := metric.NewView( + metric.Instrument{ + Name: PopulateJunoMetricNamePrefix("inbound"), + Scope: instrumentation.Scope{Name: MeterName}, + }, + metric.Stream{ + Aggregation: aggregation.ExplicitBucketHistogram{ + Boundaries: config.HistogramBuckets.Inbound, + }, + }, + ) + + outboundBucketsView := metric.NewView( + metric.Instrument{ + Name: PopulateJunoMetricNamePrefix("outbound_connection"), + Scope: instrumentation.Scope{Name: MeterName}, + }, + metric.Stream{ + Aggregation: aggregation.ExplicitBucketHistogram{ + Boundaries: config.HistogramBuckets.OutboundConnection, + }, + }, + ) - provider, err := NewMeterProvider(ctx, *config, repBucketsView) + var err error + meterProvider, err = NewMeterProvider(ctx, *config, repBucketsView, ssConnBucketsView, inboundBucketsView, outboundBucketsView) if err != nil { log.Fatal(err) } - provider.Meter(MeterName) - global.SetMeterProvider(provider) } func NewMeterProvider(ctx context.Context, cfg otelCfg.Config, vis ...metric.View) (*metric.MeterProvider, error) { @@ -216,32 +156,32 @@ func NewMeterProvider(ctx context.Context, cfg otelCfg.Config, vis ...metric.Vie // Set the reader collection periord to 10 seconds (default 60). reader := metric.NewPeriodicReader(exp, metric.WithInterval(time.Duration(cfg.Resolution)*time.Second)) - meterProvider = metric.NewMeterProvider( + metProvider := metric.NewMeterProvider( metric.WithResource(res), metric.WithReader(reader), metric.WithView(vis...), ) - return meterProvider, nil + return metProvider, nil } func NewHTTPExporter(ctx context.Context) (metric.Exporter, error) { + header := make(map[string]string) var deltaTemporalitySelector = func(metric.InstrumentKind) metricdata.Temporality { return metricdata.DeltaTemporality } if otelCfg.OtelConfig.UseTls == true { return otlpmetrichttp.New( ctx, otlpmetrichttp.WithEndpoint(otelCfg.OtelConfig.Host+":"+fmt.Sprintf("%d", otelCfg.OtelConfig.Port)), - //otlpmetrichttp.WithInsecure(), // WithTimeout sets the max amount of time the Exporter will attempt an // export. - //func(metric.InstrumentKindSyncHistogram){return metricdata.DeltaTemporality} - otlpmetrichttp.WithTimeout(7*time.Second), + otlpmetrichttp.WithTimeout(20*time.Second), otlpmetrichttp.WithCompression(otlpmetrichttp.NoCompression), otlpmetrichttp.WithTemporalitySelector(deltaTemporalitySelector), + otlpmetrichttp.WithHeaders(header), otlpmetrichttp.WithRetry(otlpmetrichttp.RetryConfig{ // Enabled indicates whether to not retry sending batches in case // of export failure. - Enabled: true, + Enabled: false, // InitialInterval the time to wait after the first failure before // retrying. InitialInterval: 1 * time.Second, @@ -252,8 +192,9 @@ func NewHTTPExporter(ctx context.Context) (metric.Exporter, error) { // MaxElapsedTime is the maximum amount of time (including retries) // spent trying to send a request/batch. Once this value is // reached, the data is discarded. - MaxElapsedTime: 240 * time.Second, + MaxElapsedTime: 20 * time.Second, }), + otlpmetrichttp.WithURLPath(otelCfg.OtelConfig.UrlPath), ) } else { return otlpmetrichttp.New( @@ -263,12 +204,14 @@ func NewHTTPExporter(ctx context.Context) (metric.Exporter, error) { otlpmetrichttp.WithTimeout(7*time.Second), otlpmetrichttp.WithCompression(otlpmetrichttp.NoCompression), otlpmetrichttp.WithTemporalitySelector(deltaTemporalitySelector), + otlpmetrichttp.WithHeaders(header), otlpmetrichttp.WithRetry(otlpmetrichttp.RetryConfig{ Enabled: true, InitialInterval: 1 * time.Second, MaxInterval: 10 * time.Second, MaxElapsedTime: 240 * time.Second, }), + otlpmetrichttp.WithURLPath(otelCfg.OtelConfig.UrlPath), ) } @@ -284,73 +227,43 @@ func IsEnabled() bool { return meterProvider != nil } -func GetHistogramForOperation() (syncint64.Histogram, error) { - var err error - apiHistogramOnce.Do(func() { - meter := global.Meter(MeterName) - apiHistogram, err = meter.SyncInt64().Histogram( - PopulateJunoMetricNamePrefix("inbound"), - instrument.WithDescription("Histogram for Juno API"), - instrument.WithUnit(unit.Milliseconds), - ) - - }) - return apiHistogram, err -} - -func GetHistogramForReplication() (syncint64.Histogram, error) { - var err error - replicationHistogramOnce.Do(func() { - meter := global.Meter(MeterName) - replicationHistogram, err = meter.SyncInt64().Histogram( - PopulateJunoMetricNamePrefix("replication"), - instrument.WithDescription("Histogram for Juno replication"), - instrument.WithUnit(unit.Milliseconds), - ) - - }) - return replicationHistogram, err -} - -func GetHistogramForReplicationConnect() (syncint64.Histogram, error) { - var err error - connectHistogramOnce.Do(func() { - meter := global.Meter(MeterName) - connectHistogram, err = meter.SyncInt64().Histogram( - PopulateJunoMetricNamePrefix("outbound_connection"), - instrument.WithDescription("Histogram for Juno connection"), - instrument.WithUnit(unit.Milliseconds), - ) - - }) - return connectHistogram, err -} - -func GetHistogramForSSConnect() (syncint64.Histogram, error) { - var err error - ssConnectHistogramOnce.Do(func() { - meter := global.Meter(MeterName) - ssConnectHistogram, err = meter.SyncInt64().Histogram( - PopulateJunoMetricNamePrefix("ssConnection"), - instrument.WithDescription("Histogram for Juno SS connection failure"), - instrument.WithUnit(unit.Milliseconds), - ) - - }) - return ssConnectHistogram, err +func getHistogram(histName CMetric) (chan DataPoint, error) { + if histMetric, ok := histMetricMap[histName]; ok { + histMetric.createHistogram.Do(func() { + meter := meterProvider.Meter(MeterName) + histMetric.histogram, _ = meter.Int64Histogram( + histMetric.metricName, + instrument.WithDescription(histMetric.metricDesc), + instrument.WithUnit(histMetric.metricUnit), + ) + histMetric.doneCh = make(chan bool) + histMetric.histogramCh = make(chan DataPoint, histChannelSize) + go doWriteHistogram(histMetric.histogramCh, histMetric.doneCh, histMetric.histogram) + }) + if histMetric.histogramCh != nil { + return histMetric.histogramCh, nil + } else { + return nil, errors.New("Histogram Object not Ready") + } + } else { + return nil, errors.New("No Such Histogram exists") + } } -func GetCounter(counterName CMetric) (syncint64.Counter, error) { +func GetCounter(counterName CMetric) (chan DataPoint, error) { if counterMetric, ok := countMetricMap[counterName]; ok { counterMetric.createCounter.Do(func() { - meter := global.Meter(MeterName) - counterMetric.counter, _ = meter.SyncInt64().Counter( + meter := meterProvider.Meter(MeterName) + counterMetric.counter, _ = meter.Int64Counter( PopulateJunoMetricNamePrefix(counterMetric.metricName), instrument.WithDescription(counterMetric.metricDesc), ) + counterMetric.doneCh = make(chan bool) + counterMetric.counterCh = make(chan DataPoint, counterChannelSize) + go doWriteCounter(counterMetric.counterCh, counterMetric.doneCh, counterMetric.counter) }) - if counterMetric.counter != nil { - return counterMetric.counter, nil + if counterMetric.counterCh != nil { + return counterMetric.counterCh, nil } else { return nil, errors.New("Counter Object not Ready") } @@ -360,154 +273,130 @@ func GetCounter(counterName CMetric) (syncint64.Counter, error) { } // This is the pp.app.intbound metric -func RecordOperation(opType string, status string, latency int64) { - ctx := context.Background() - if operation, err := GetHistogramForOperation(); err == nil { - commonLabels := []attribute.KeyValue{ - attribute.String("operation", opType), - attribute.String("status", status), +func RecordOperation(opType string, status proto.OpStatus, latency int64) { + if IsEnabled() { + if opsHistChannel, err := getHistogram(Inbound); err == nil { + commonLabels := instrument.WithAttributes( + attribute.String("endpoint", opType), + attribute.String("error_reason", status.ShortNameString()), + attribute.String("status", logging.CalStatus(status).CalStatus()), + ) + dataPoint := DataPoint{commonLabels, latency} + if opsHistChannel != nil && len(opsHistChannel) < histChannelSize { + opsHistChannel <- dataPoint + } } - operation.Record(ctx, latency, commonLabels...) } } func RecordReplication(opType string, status string, destination string, latency int64) { - ctx := context.Background() - if replication, err := GetHistogramForReplication(); err == nil { - commonLabels := []attribute.KeyValue{ - attribute.String("operation", opType), - attribute.String("status", status), - attribute.String("dest_az", destination), + if IsEnabled() { + if replHistChannel, err := getHistogram(Replication); err == nil { + commonLabels := instrument.WithAttributes( + attribute.String("operation", opType), + attribute.String("status", status), + attribute.String("dest_az", destination), + ) + dataPoint := DataPoint{commonLabels, latency} + if replHistChannel != nil && len(replHistChannel) < histChannelSize { + replHistChannel <- dataPoint + } } - replication.Record(ctx, latency, commonLabels...) } } func RecordSSConnection(endpoint string, status string, latency int64) { - ctx := context.Background() - if ssConnect, err := GetHistogramForSSConnect(); err == nil { - commonLabels := []attribute.KeyValue{ - attribute.String("endpoint", endpoint), - attribute.String("status", status), + if IsEnabled() { + if ssConnHistChannel, err := getHistogram(SSConnection); err == nil { + commonLabels := instrument.WithAttributes( + attribute.String("endpoint", endpoint), + attribute.String("status", status), + ) + dataPoint := DataPoint{commonLabels, latency} + if ssConnHistChannel != nil && len(ssConnHistChannel) < histChannelSize { + ssConnHistChannel <- dataPoint + } } - ssConnect.Record(ctx, latency, commonLabels...) } } func RecordOutboundConnection(endpoint string, status string, latency int64) { - ctx := context.Background() - if requestLatency, err := GetHistogramForReplicationConnect(); err == nil { - commonLabels := []attribute.KeyValue{ - attribute.String("endpoint", endpoint), - attribute.String("status", status), + if IsEnabled() { + if outBoundHistChannel, err := getHistogram(OutboundConnection); err == nil { + commonLabels := instrument.WithAttributes( + attribute.String(Endpoint, endpoint), + attribute.String("status", status), + ) + dataPoint := DataPoint{commonLabels, latency} + if outBoundHistChannel != nil && len(outBoundHistChannel) < histChannelSize { + outBoundHistChannel <- dataPoint + } } - requestLatency.Record(ctx, latency, commonLabels...) } } func RecordCount(counterName CMetric, tags []Tags) { - ctx := context.Background() - if counter, err := GetCounter(counterName); err == nil { - if len(tags) != 0 { - // commonLabels := []attribute.KeyValue{ - // attribute.String("endpoint", endpoint), - // } - commonLabels := covertTagsToOTELAttributes(tags) - counter.Add(ctx, 1, commonLabels...) + if IsEnabled() { + if counterChannel, err := GetCounter(counterName); err == nil { + var commonLabels instrument.MeasurementOption + if len(tags) != 0 { + commonLabels = covertTagsToOTELAttributes(tags) + } + dataPoint := DataPoint{commonLabels, 1} + if counterChannel != nil && len(counterChannel) < counterChannelSize { + counterChannel <- dataPoint + } } else { - counter.Add(ctx, 1) + glog.Error(err) } - } else { - glog.Error(err) } } -func covertTagsToOTELAttributes(tags []Tags) (attr []attribute.KeyValue) { - attr = make([]attribute.KeyValue, len(tags)) +func covertTagsToOTELAttributes(tags []Tags) instrument.MeasurementOption { + attr := make([]attribute.KeyValue, len(tags)) for i := 0; i < len(tags); i++ { attr[i] = attribute.String(tags[i].TagName, tags[i].TagValue) } - return + return instrument.WithAttributes(attr...) } func PopulateJunoMetricNamePrefix(metricName string) string { return JUNO_METRIC_PREFIX + metricName } -// getEnvFromSyshieraYaml returns the env: line from /etc/syshiera.yaml -func getEnvFromSyshieraYaml() (string, error) { - filePath := "/etc/syshiera.yaml" - file, err := os.Open(filePath) - if err != nil { - return "", err - } - defer file.Close() - fileReader := bufio.NewReader(file) - scanner := bufio.NewScanner(fileReader) - for scanner.Scan() { - line := scanner.Text() - err = scanner.Err() - if err != nil { - if err == io.EOF { - break - } - return "", err - } - pos := strings.Index(line, "pp_az: ") - if pos == -1 { - continue - } - return strings.TrimSpace(line[3:len(line)]), nil - } - err = errors.New("dc: not found in /etc/syshiera.yaml") - return "", err -} - func getResourceInfo(appName string) *resource.Resource { - colo, _err := getEnvFromSyshieraYaml() - if _err != nil { - colo = "qa" - } hostname, _ := os.Hostname() - resource := resource.NewWithAttributes("empty resource", - semconv.HostNameKey.String(hostname), - semconv.HostTypeKey.String("BM"), - semconv.ServiceNameKey.String(appName), - attribute.String("az", colo), + attribute.String("host", hostname), attribute.String("application", appName), ) return resource } -// func NewGRPCExporter(ctx context.Context) (metric.Exporter, error) { -// ctx, cancel := context.WithTimeout(ctx, time.Second*10) -// defer cancel() - -// // Exponential back-off strategy. -// backoffConf := backoff.DefaultConfig -// // You can also change the base delay, multiplier, and jitter here. -// backoffConf.MaxDelay = 240 * time.Second - -// conn, err := grpc.DialContext( -// ctx, -// string(DEFAULT_OTEL_COLLECTOR__IP+":"+DEFAULT_GRPC_OTEL_COLLECTOR_PORT), -// grpc.WithInsecure(), -// grpc.WithBlock(), -// grpc.WithConnectParams(grpc.ConnectParams{ -// Backoff: backoffConf, -// // Connection timeout. -// MinConnectTimeout: 5 * time.Second, -// }), -// ) -// if err != nil { -// return nil, err -// } - -// return otlpmetricgrpc.New(ctx, -// otlpmetricgrpc.WithGRPCConn(conn), -// // WithTimeout sets the max amount of time the Exporter will attempt an -// // export. -// otlpmetricgrpc.WithTimeout(7*time.Second), -// ) -// } +func doWriteHistogram(histChannel chan DataPoint, doneCh chan bool, hist instrument.Int64Histogram) { + ctx := context.Background() + for { + select { + case dataPoint := <-histChannel: + hist.Record(ctx, dataPoint.data, dataPoint.attr) + case <-doneCh: + return + } + } +} + +func doWriteCounter(counterChannel chan DataPoint, doneCh chan bool, count instrument.Int64Counter) { + ctx := context.Background() + for { + select { + case dataPoint := <-counterChannel: + if dataPoint.attr != nil { + count.Add(ctx, dataPoint.data, dataPoint.attr) + } else { + count.Add(ctx, dataPoint.data) + } + case <-doneCh: + return + } + } +} diff --git a/pkg/logging/otel/statsLogger.go b/pkg/logging/otel/statsLogger.go index f93031f5..a0c9e7e4 100644 --- a/pkg/logging/otel/statsLogger.go +++ b/pkg/logging/otel/statsLogger.go @@ -1,194 +1,103 @@ +// Copyright 2023 PayPal Inc. // -// Copyright 2023 PayPal Inc. +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at // -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// http://www.apache.org/licenses/LICENSE-2.0 // +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package otel import ( "context" "errors" "fmt" - "juno/pkg/stats" + + "github.com/paypal/junodb/third_party/forked/golang/glog" "runtime" "strconv" - "sync" - "time" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/global" - "go.opentelemetry.io/otel/metric/instrument" - "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" -) - -const ( - MachineCpuUsed string = string("machineCpuUsed") - ProcessCpuUsed string = string("machineCpuUsed") - MachineMemoryUsed - ProcessMemoryUsed -) -var ( - machineCpuUsedOnce sync.Once - processCpuUsedOnce sync.Once - machineMemoryUsedOnce sync.Once - processMemoryUsedOnce sync.Once - badShardOnce sync.Once - alertShardOnce sync.Once - warningShardOnce sync.Once - keyCountOnce sync.Once - freeStorageOnce sync.Once - usedStorageOnce sync.Once - LNLevelOnce sync.Once - compSecOnce sync.Once - compCountOnce sync.Once - pendingCompOnce sync.Once - stallOnce sync.Once -) + "github.com/paypal/junodb/pkg/stats" -var ( - machTime time.Time - machCpuTick uint16 - machUser uint64 - machSystem uint64 + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" ) -type GaugeMetric struct { - MetricName string - metricDesc string - gaugeMetric asyncfloat64.Gauge - createGauge *sync.Once - stype ServerType -} - -var GaugeMetricMap map[string]*GaugeMetric = map[string]*GaugeMetric{ - "mCPU": {"machCpuUsed", "CPU utilization of the host", nil, &machineCpuUsedOnce, SvrTypeAll}, - "pCPU": {"procCpuUsed", "CPU utilization of individual Juno instance", nil, &processCpuUsedOnce, SvrTypeAll}, - "mMem": {"machMemUsed", "Memory utilization of the host", nil, &machineMemoryUsedOnce, SvrTypeAll}, - "pMem": {"procMemUsed", "Memory utilization of individual Juno instance", nil, &processMemoryUsedOnce, SvrTypeAll}, - - "nBShd": {"badShard", "Number of bad shards", nil, &badShardOnce, SvrTypeProxy}, - "nAShd": {"alertShard", "number of shards with no redundancy", nil, &alertShardOnce, SvrTypeProxy}, - "nWShd": {"warningShard", "number of shards with bad SS", nil, &warningShardOnce, SvrTypeProxy}, - - "keys": {"key_count", "Key Counte in rocksDB", nil, &keyCountOnce, SvrTypeStorage}, - "free": {"free_mb_storage_space", "Free Storage Space (mbytes)", nil, &freeStorageOnce, SvrTypeStorage}, - "used": {"storage_used_mb", "Used Storage Space (mbytes)", nil, &usedStorageOnce, SvrTypeStorage}, - "LN": {"LN_level", "Max LN Level in Rocksdb", nil, &LNLevelOnce, SvrTypeStorage}, - "compSec": {"comp_sec", "Compaction Sec", nil, &compSecOnce, SvrTypeStorage}, - "compCount": {"comp_count", "Compaction Count", nil, &compCountOnce, SvrTypeStorage}, - "pCompKB": {"pending_comp_kbytes", "Pending Compaction KBytes", nil, &pendingCompOnce, SvrTypeStorage}, - "stall": {"stall_write_rate", "Actural Delayed Write Rate", nil, &stallOnce, SvrTypeStorage}, -} - -// Represents the list of workers with stats -type CurrentStatsData struct { - WorkerState []WorkerStats -} - -// Represents list of stats emitted by a worker -type WorkerStats struct { - StatData []StateData -} - -// Represents stats by worker -type StateData struct { - Name string - Value float64 - Dimensions []attribute.KeyValue -} - -var CurrStatsData CurrentStatsData - func InitSystemMetrics(serverType ServerType, workerStats [][]stats.IState) { - meter := global.Meter(MeterName) - var stateLogGauge []instrument.Asynchronous = make([]instrument.Asynchronous, len(GaugeMetricMap)) - var i int = 0 - //InitMachCpuUsage() - for _, element := range GaugeMetricMap { + meter := meterProvider.Meter(MeterName) + var metricList []metric.Observable = make([]metric.Observable, 0, len(GaugeMetricList)) + for _, element := range GaugeMetricList { if element.stype == serverType || element.stype == SvrTypeAll { element.createGauge.Do(func() { - // TODO instead of element use GaugeMetricMap[index] - element.gaugeMetric, _ = meter.AsyncFloat64().Gauge( + var err error + element.gaugeMetric, err = meter.Float64ObservableGauge( PopulateJunoMetricNamePrefix(element.MetricName), - //instrument.WithUnit(unit.Dimensionless), - instrument.WithDescription(element.metricDesc), + metric.WithDescription(element.metricDesc), ) - stateLogGauge[i] = element.gaugeMetric - i++ + metricList = append(metricList, element.gaugeMetric) + if err != nil { + glog.Error("FloatObservable creation failed : ", err.Error()) + } }) } } - if err := meter.RegisterCallback( - stateLogGauge, - func(ctx context.Context) { - wstate := getMetricData(workerStats) - for _, workerState := range wstate { - for _, state := range workerState.StatData { - gMetric, ok := GaugeMetricMap[state.Name] - if ok { - if gMetric.gaugeMetric != nil { - gMetric.gaugeMetric.Observe(ctx, state.Value, state.Dimensions...) - } - } + if _, err := meter.RegisterCallback(func(_ context.Context, o metric.Observer) error { + getMetricData(workerStats) + for _, metric := range GaugeMetricList { + if metric.gaugeMetric != nil { + for _, stat := range metric.stats { + o.ObserveFloat64(metric.gaugeMetric, stat.Value, stat.Dimensions) } } - }, - ); err != nil { - ///Just ignore + } + return nil + }, metricList...); err != nil { + glog.Error("Error Registering call back : ", err.Error()) } + } -func getMetricData(workerStats [][]stats.IState) []WorkerStats { +func getMetricData(workerStats [][]stats.IState) { numWorkers := len(workerStats) - var wsd []WorkerStats - wsd = make([]WorkerStats, numWorkers) - for wi := 0; wi < numWorkers; wi++ { // For number of workers - var sdata []StateData - sdata = make([]StateData, 0, len(workerStats[wi])) - for _, v := range workerStats[wi] { // For number of statistics - if fl, err := strconv.ParseFloat(v.State(), 64); err == nil { - if wrstats, err := writeMetricsData(wi, v.Header(), fl); err == nil { - sdata = append(sdata, wrstats) + for _, metric := range GaugeMetricList { + if metric.gaugeMetric != nil { + metric.stats = make([]StateData, 0, numWorkers) + for wi := 0; wi < numWorkers; wi++ { // For number of workers + for _, v := range workerStats[wi] { // For number of statistics + if metric.MetricShortName == v.Header() { + if fl, err := strconv.ParseFloat(v.State(), 64); err == nil { + if wrstats, err := writeMetricsData(wi, v.Header(), fl); err == nil { + metric.stats = append(metric.stats, wrstats) + } + } + } } } } - wsd[wi].StatData = sdata } - - return wsd + return } func writeMetricsData(wid int, key string, value float64) (StateData, error) { var data StateData - _, ok := GaugeMetricMap[key] - if !ok { - // Only record the metrics in the map - return data, errors.New("Metirc not found in Map") - } - if (key == "mCPU" || key == "mMem") && wid != 0 { + if (key == "free" || key == "used") && wid != 0 { // Log system metric only for worker 0 return data, errors.New("Do not log machine resource utilization for all workers except for worker 0") } data.Name = key data.Value = value - data.Dimensions = []attribute.KeyValue{attribute.String("id", fmt.Sprintf("%d", wid))} + data.Dimensions = metric.WithAttributes(attribute.String("id", fmt.Sprintf("%d", wid))) return data, nil } diff --git a/pkg/logging/otel/test/logger_test.go b/pkg/logging/otel/test/logger_test.go index f8117449..555ec431 100644 --- a/pkg/logging/otel/test/logger_test.go +++ b/pkg/logging/otel/test/logger_test.go @@ -19,15 +19,16 @@ // This test uses a mock to validate the metrics and the sends the metric to // QA OTEL collector for verifying the results in Sfx UI. -package test +package otel import ( "fmt" - "juno/pkg/logging/otel" - config "juno/pkg/logging/otel/config" - "juno/pkg/stats" "testing" "time" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/logging/otel" + config "github.com/paypal/junodb/pkg/logging/otel/config" + "github.com/paypal/junodb/pkg/stats" ) var exportinterval int = 10 @@ -50,13 +51,13 @@ func TestJunoOperation(t *testing.T) { time.Sleep(time.Duration(1) * time.Second) - otel.RecordOperation("Create", "SUCCESS", 2000) - otel.RecordOperation("Get", "SUCCESS", 1000) - otel.RecordOperation("Update", "SUCCESS", 3000) - otel.RecordOperation("Destroy", "SUCCESS", 500) - otel.RecordOperation("Set", "SUCCESS", 2500) + otel.RecordOperation("Create", proto.OpStatusNoError, 2000) + otel.RecordOperation("Get", proto.OpStatusNoError, 1000) + otel.RecordOperation("Update", proto.OpStatusNoError, 3000) + otel.RecordOperation("Destroy", proto.OpStatusNoError, 500) + otel.RecordOperation("Set", proto.OpStatusNoError, 2500) - otel.RecordOperation("Create", "ERROR", 2000) + otel.RecordOperation("Create", proto.OpStatusBadParam, 2000) time.Sleep(time.Duration(SfxConfig.Resolution) * time.Second) @@ -357,14 +358,14 @@ func TestJunoStats(t *testing.T) { for i := 0; i < 2; i++ { workerStats[i] = append(workerStats[i], []stats.IState{ - stats.NewUint32State(&mcpu, "mCPU", "Machine CPU usage"), + stats.NewUint32State(&mcpu, "pCPU", "Process CPU usage"), stats.NewUint16State(&bshd, "nBShd", "number of Bad Shards"), }...) } otel.InitSystemMetrics(otel.SvrTypeProxy, workerStats) - time.Sleep(time.Duration(SfxConfig.Resolution) * time.Second) + time.Sleep(time.Duration(SfxConfig.Resolution+10) * time.Second) v1m := mc.GetMetrics() @@ -372,11 +373,11 @@ func TestJunoStats(t *testing.T) { t.Errorf("Test fail") } else { for i := 0; i < 2; i++ { - if v1m[i].GetName() == "juno.server.machCpuUsed" { + if v1m[i].GetName() == "pp.juno.server.proc_cpu_used" { if v1m[i].GetGauge().DataPoints[0].GetAsDouble() != 30 { t.Errorf("CPU utilization is incorrect %f", v1m[i].GetGauge().DataPoints[0].GetAsDouble()) } - } else if v1m[i].GetName() == "juno.server.badShard" { + } else if v1m[i].GetName() == "pp.juno.server.bad_shard" { if v1m[i].GetGauge().DataPoints[0].GetAsDouble() != 5 { t.Errorf("Bad Shard Count is incorrect %f", v1m[i].GetGauge().DataPoints[0].GetAsDouble()) } diff --git a/pkg/logging/otel/test/mock_collector.go b/pkg/logging/otel/test/mock_collector.go index 5b29af06..fc8c1989 100644 --- a/pkg/logging/otel/test/mock_collector.go +++ b/pkg/logging/otel/test/mock_collector.go @@ -16,7 +16,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -package test +package otel import ( "bytes" @@ -31,6 +31,7 @@ import ( "encoding/pem" "fmt" "io" + "io/ioutil" "math/big" mathrand "math/rand" "net" @@ -112,7 +113,7 @@ func (c *mockCollector) serveMetrics(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) return } - + // fmt.Println("---------------raw req--------------", rawRequest) request, err := unmarshalMetricsRequest(rawRequest, r.Header.Get("content-type")) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -122,7 +123,7 @@ func (c *mockCollector) serveMetrics(w http.ResponseWriter, r *http.Request) { c.spanLock.Lock() defer c.spanLock.Unlock() - // fmt.Println("---------------serveMetrics--------------", request) + fmt.Println("---------------serveMetrics--------------", request) c.metricsStorage.AddMetrics(request) } @@ -161,7 +162,7 @@ func readRequest(r *http.Request) ([]byte, error) { if r.Header.Get("Content-Encoding") == "gzip" { return readGzipBody(r.Body) } - return io.ReadAll(r.Body) + return ioutil.ReadAll(r.Body) } func readGzipBody(body io.Reader) ([]byte, error) { @@ -334,8 +335,13 @@ func NewMetricsStorage() MetricsStorage { func (s *MetricsStorage) AddMetrics(request *collectormetricpb.ExportMetricsServiceRequest) { for _, rm := range request.GetResourceMetrics() { // TODO (rghetia) handle multiple resource and library info. + fmt.Println("---------------AddMetrics------------------", rm) + if len(rm.ScopeMetrics) > 0 { s.metrics = append(s.metrics, rm.ScopeMetrics[0].Metrics...) + fmt.Println("Metric added successfully") + } else { + fmt.Println("Metrics added filed") } // if len(rm.InstrumentationLibraryMetrics) > 0 { diff --git a/pkg/net/netutil/netutil.go b/pkg/net/netutil/netutil.go index 03665f71..90c46f8c 100644 --- a/pkg/net/netutil/netutil.go +++ b/pkg/net/netutil/netutil.go @@ -22,7 +22,7 @@ package netutil import ( "net" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/pkg/proto/cryptoks.go b/pkg/proto/cryptoks.go index 71f04d14..8cf9a153 100644 --- a/pkg/proto/cryptoks.go +++ b/pkg/proto/cryptoks.go @@ -24,7 +24,7 @@ import ( "errors" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type ( diff --git a/pkg/proto/decode.go b/pkg/proto/decode.go index 2273be5d..43baccbe 100644 --- a/pkg/proto/decode.go +++ b/pkg/proto/decode.go @@ -22,9 +22,9 @@ package proto import ( "io" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) const ( @@ -69,7 +69,7 @@ func (dec *Decoder) Decode(op *OperationalMessage) error { return op.decode(raw, &header, true) } -//Caller's responsibility to have op zeroed +// Caller's responsibility to have op zeroed func (op *OperationalMessage) decode(raw []byte, msgHeader *messageHeaderT, copyData bool) error { offset := 0 szBuf := len(raw) diff --git a/pkg/proto/mayfly/mapping.go b/pkg/proto/mayfly/mapping.go index b9d292c8..f4d8ab99 100644 --- a/pkg/proto/mayfly/mapping.go +++ b/pkg/proto/mayfly/mapping.go @@ -23,9 +23,9 @@ import ( "encoding/binary" "net" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) func opCodeToJuno(mfop OpCode) (opcode proto.OpCode, err error) { @@ -69,7 +69,7 @@ func toMayflyOpCode(jop proto.OpCode) (opcode OpCode, err error) { return } -///TODO to be reviewed +// /TODO to be reviewed var opStatusJunoToMayflyMapping []OpStatus = []OpStatus{ OpStatusdNoError, //Ok, 0 OpStatusBadMsg, //BadMsg, 1 diff --git a/pkg/proto/mayfly/msg.go b/pkg/proto/mayfly/msg.go index 97b52762..643af4d7 100644 --- a/pkg/proto/mayfly/msg.go +++ b/pkg/proto/mayfly/msg.go @@ -25,7 +25,7 @@ import ( "fmt" "io" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) type Msg struct { diff --git a/pkg/proto/mayfly/msg_test.go b/pkg/proto/mayfly/msg_test.go index 46dbca45..1988eff9 100644 --- a/pkg/proto/mayfly/msg_test.go +++ b/pkg/proto/mayfly/msg_test.go @@ -23,7 +23,7 @@ import ( "bytes" "testing" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) func testRequestResponse(t *testing.T, rawRequest []byte, rawResponse []byte) { diff --git a/pkg/proto/mayfly/opmsg.go b/pkg/proto/mayfly/opmsg.go index a1eddce7..8a3c4b7c 100644 --- a/pkg/proto/mayfly/opmsg.go +++ b/pkg/proto/mayfly/opmsg.go @@ -30,8 +30,8 @@ import ( "sync/atomic" "time" - "juno/pkg/net/netutil" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/net/netutil" + "github.com/paypal/junodb/pkg/util" ) type ( diff --git a/pkg/proto/metaField.go b/pkg/proto/metaField.go index aace1d4c..c5f45776 100644 --- a/pkg/proto/metaField.go +++ b/pkg/proto/metaField.go @@ -18,53 +18,53 @@ // /* - ============================== - *** Predefined Field Types *** - ============================== - - Tag/ID | Field | SizeType - -------+--------------------------------------+------ - 0x01 | TimeToLive | 0x01 - 0x02 | Version | 0x01 - 0x03 | Creation Time | 0x01 - 0x04 | Expiration Time | 0x01 - 0x05 | RequestID/UUID | 0x03 - 0x06 | Source Info | 0 - 0x07 | Last Modification time (nano second) | 0x02 - 0x08 | Originator RequestID/UUID | 0x03 - 0x09 | Correlation ID | 0 - 0x0a | RequestHandlingTime | 0x01 - 0x0b | UDF Name | 0 - -------+--------------------------------------+------ - - - Tag/ID: 0x06 - +-----------------------------------------------------------------------------------------------+ - | 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| - | 0| 1| 2| 3| - +-----------+-----------+--------------------+--+-----------------------+-----------------------+ - | size (include padding)| app name length | T| Port | - +-----------------------+--------------------+--+-----------------------------------------------+ - | IPv4 address if T is 0 or IPv6 address if T is 1 | - +-----------------------------------------------------------------------------------------------+ - | application name, padding to 4-byte aligned | - +-----------------------------------------------------------------------------------------------+ - - Tag/ID: 0x09; 0x0b - +----+------------------------------------------- - | 0 | field size (including padding) - +----+------------------------------------------- - | 1 | octet sequence length - +----+------------------------------------------- - | | octet sequence, padding to 4-byte aligned - +----+------------------------------------------- + ============================== + *** Predefined Field Types *** + ============================== + + Tag/ID | Field | SizeType + -------+--------------------------------------+------ + 0x01 | TimeToLive | 0x01 + 0x02 | Version | 0x01 + 0x03 | Creation Time | 0x01 + 0x04 | Expiration Time | 0x01 + 0x05 | RequestID/UUID | 0x03 + 0x06 | Source Info | 0 + 0x07 | Last Modification time (nano second) | 0x02 + 0x08 | Originator RequestID/UUID | 0x03 + 0x09 | Correlation ID | 0 + 0x0a | RequestHandlingTime | 0x01 + 0x0b | UDF Name | 0 + -------+--------------------------------------+------ + + + Tag/ID: 0x06 + +-----------------------------------------------------------------------------------------------+ + | 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7| + | 0| 1| 2| 3| + +-----------+-----------+--------------------+--+-----------------------+-----------------------+ + | size (include padding)| app name length | T| Port | + +-----------------------+--------------------+--+-----------------------------------------------+ + | IPv4 address if T is 0 or IPv6 address if T is 1 | + +-----------------------------------------------------------------------------------------------+ + | application name, padding to 4-byte aligned | + +-----------------------------------------------------------------------------------------------+ + + Tag/ID: 0x09; 0x0b + +----+------------------------------------------- + | 0 | field size (including padding) + +----+------------------------------------------- + | 1 | octet sequence length + +----+------------------------------------------- + | | octet sequence, padding to 4-byte aligned + +----+------------------------------------------- */ package proto import ( "net" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // Meta Component Field Tag @@ -173,7 +173,7 @@ func (t requestHandlingTimeT) tagAndSizeTypeByte() uint8 { return kFieldTagRequestHandlingTime | kMetaField_4Bytes } -//uint64 meta field +// uint64 meta field func (t uint64T) isSet() bool { return t != 0 } @@ -212,7 +212,7 @@ func (t lastModificationTimeT) tagAndSizeTypeByte() uint8 { return kFieldTagLastModificationTime | kMetaField_8Bytes } -//16-byte meta field +// 16-byte meta field func (t *requestIdBaseT) value() []byte { return t.Bytes() } @@ -270,7 +270,7 @@ func (t *originatorT) tagAndSizeTypeByte() uint8 { return kFieldTagOriginatorRequestID | kMetaField_16Bytes } -//sourceinfo +// sourceinfo func (t *sourceInfoT) isSet() bool { if (len(t.ip) != 0) || (t.port != 0) || (len(t.appName) != 0) { return true @@ -379,7 +379,7 @@ func (t sourceInfoT) tagAndSizeTypeByte() uint8 { return kFieldTagSourceInfo | kMetaFieldVariableSize } -//byte sequence +// byte sequence func (t byteSequenceT) isSet() bool { return len(t) != 0 } diff --git a/pkg/proto/opMsg.go b/pkg/proto/opMsg.go index 74ddd893..f2616587 100644 --- a/pkg/proto/opMsg.go +++ b/pkg/proto/opMsg.go @@ -27,7 +27,7 @@ import ( uuid "github.com/satori/go.uuid" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" ) type OperationalMessage struct { diff --git a/pkg/proto/opMsg_test.go b/pkg/proto/opMsg_test.go index 555a03b4..fd4946a4 100644 --- a/pkg/proto/opMsg_test.go +++ b/pkg/proto/opMsg_test.go @@ -23,8 +23,9 @@ import ( "bytes" "encoding/binary" "fmt" - "juno/pkg/util" "testing" + + "github.com/paypal/junodb/pkg/util" ) func testRequestResponse(t *testing.T, rawRequest []byte, rawResponse []byte) { diff --git a/pkg/proto/payload.go b/pkg/proto/payload.go index e1bf4bdf..ae61c152 100644 --- a/pkg/proto/payload.go +++ b/pkg/proto/payload.go @@ -28,9 +28,9 @@ import ( "fmt" "io" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/util" "github.com/golang/snappy" ) @@ -106,7 +106,7 @@ func (p *Payload) SetWithClearValue(value []byte) { p.data = value } -///TODO +// /TODO func (p *Payload) GetClearValue() (value []byte, err error) { if p.GetLength() == 0 { return diff --git a/pkg/proto/rawmessage.go b/pkg/proto/rawmessage.go index 5fb11782..ea2e7e6e 100644 --- a/pkg/proto/rawmessage.go +++ b/pkg/proto/rawmessage.go @@ -23,10 +23,10 @@ import ( "bytes" "io" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/debug" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/debug" + "github.com/paypal/junodb/pkg/util" ) type RawMessage struct { @@ -95,9 +95,7 @@ func (m *RawMessage) allocateBuffer(size int) { m.body = m.buf.Bytes() } -// // Note: read timeout is set at conn level -// func (msg *RawMessage) Read(r io.Reader) (n int, err error) { var hBuffer [kMessageHeaderSize]byte @@ -152,9 +150,7 @@ func (msg *RawMessage) ReadWithHeader(header []byte, r io.Reader) (n int, err er return } -// // Note: this api is not thread safe -// func (m *RawMessage) Write(w io.Writer) (n int, err error) { var mheader [kMessageHeaderSize]byte raw := mheader[:] diff --git a/pkg/sec/certs.go b/pkg/sec/certs.go index cacc680e..fa0b4666 100644 --- a/pkg/sec/certs.go +++ b/pkg/sec/certs.go @@ -20,8 +20,9 @@ package sec import ( - "juno/third_party/forked/golang/glog" "os" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type localFileProtectedT struct { diff --git a/pkg/sec/certs_test.go b/pkg/sec/certs_test.go index a1a39e0b..d598b285 100644 --- a/pkg/sec/certs_test.go +++ b/pkg/sec/certs_test.go @@ -20,10 +20,11 @@ package sec import ( - "juno/third_party/forked/golang/glog" "os" "reflect" "testing" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) // Sample secrets crt, not a real crt diff --git a/pkg/sec/gotlsimpl.go b/pkg/sec/gotlsimpl.go index 47b026a5..07d7a4fa 100644 --- a/pkg/sec/gotlsimpl.go +++ b/pkg/sec/gotlsimpl.go @@ -27,9 +27,10 @@ import ( "time" "crypto/tls" - "juno/third_party/forked/golang/glog" - "juno/pkg/proto" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/pkg/proto" ) type ( @@ -67,6 +68,108 @@ func (c *TlsConn) GetStateString() string { return statStr } +func (c *TlsConn) GetTLSVersion() string { + if c.conn != nil { + stat := c.conn.ConnectionState() + return GetVersionName(stat.Version) + } + return "none" +} + +func GetVersionName(ver uint16) string { + switch ver { + case tls.VersionTLS10: + return "TLSv1" + case tls.VersionTLS11: + return "TLSv1.1" + case tls.VersionTLS12: + return "TLSv1.2" + case tls.VersionTLS13: + return "TLSv1.3" + default: + return "" + } +} + +func (c *TlsConn) GetCipherName() string { + if c.conn != nil { + stat := c.conn.ConnectionState() + return GetCipherName(stat.CipherSuite) + } + return "none" +} + +func GetCipherName(cipher uint16) string { + switch cipher { + case tls.TLS_RSA_WITH_RC4_128_SHA: + return "RSA-RC4-128-SHA" + case tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA: + return "RSA-3DES-EDE-CBC-SHA" + case tls.TLS_RSA_WITH_AES_128_CBC_SHA: + return "AES128-SHA" + case tls.TLS_RSA_WITH_AES_256_CBC_SHA: + return "AES256-SHA" + case tls.TLS_RSA_WITH_AES_128_CBC_SHA256: + return "RSA-AES-128-CBC-SHA256" + case tls.TLS_RSA_WITH_AES_128_GCM_SHA256: + return "RSA-AES-128-GCM-SHA256" + case tls.TLS_RSA_WITH_AES_256_GCM_SHA384: + return "RSA-AES-256-GCM-SHA384" + case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return "ECDHE_ECDSA_RC4_128_SHA" + case tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + return "ECDHE_ECDSA_AES128_CBC_SHA" + case tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + return "ECDHE_ECDSA_AES_256_CBC_SHA" + case tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return "ECDHE_RSA_RC4_128_SHA" + case tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "ECDHE_RSA_3DES_EDE_CBC_SHA" + case tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "ECDHE_RSA_AES128_CBC_SHA" + case tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "ECDHE_RSA_AES_256_CBC_SHA" + case tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "ECDHE_ECDSA_AES128_CBC_SHA256" + case tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "ECDHE_RSA_AES128_CBC_SHA256" + case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "ECDHE_RSA_AES128_GCM_SHA256" + case tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "ECDHE_ECDSA_AES128_GCM_SHA256" + case tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "ECDHE_RSA_AES256_GCM_SHA384" + case tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "ECDHE_ECDSA_AES256_GCM_SHA384" + case tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: + return "ECDHE_RSA_CHACHA20_POLY1305" + case tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: + return "ECDHE_ECDSA_CHACHA20_POLY1305" + case tls.TLS_AES_128_GCM_SHA256: + return "TLS_AES_128_GCM_SHA256" + case tls.TLS_AES_256_GCM_SHA384: + return "TLS_AES_256_GCM_SHA384" + case tls.TLS_CHACHA20_POLY1305_SHA256: + return "TLS_CHACHA20_POLY1305_SHA256" + case tls.TLS_FALLBACK_SCSV: + return "TLS_FALLBACK_SCSV" + default: + return "unknown" + } +} + +func (c *TlsConn) DidResume() string { + if c.conn != nil { + stat := c.conn.ConnectionState() + if stat.DidResume { + return "Yes" + } else { + return "No" + } + } + return "No" +} + func (c *TlsConn) IsServer() bool { return c.isServer } diff --git a/pkg/sec/keystore.go b/pkg/sec/keystore.go index ba29de85..d7728d7e 100644 --- a/pkg/sec/keystore.go +++ b/pkg/sec/keystore.go @@ -23,10 +23,11 @@ import ( "encoding/hex" "errors" "fmt" - "juno/pkg/proto" - "juno/third_party/forked/golang/glog" "time" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/BurntSushi/toml" ) diff --git a/pkg/sec/keystore_test.go b/pkg/sec/keystore_test.go index 3a8c0389..3e7eb737 100644 --- a/pkg/sec/keystore_test.go +++ b/pkg/sec/keystore_test.go @@ -20,10 +20,11 @@ package sec import ( - "juno/pkg/proto" "os" "reflect" "testing" + + "github.com/paypal/junodb/pkg/proto" ) var tomlData = []byte(`# Sample Keystore diff --git a/pkg/sec/seccfg.go b/pkg/sec/seccfg.go index b57344a2..883d147a 100644 --- a/pkg/sec/seccfg.go +++ b/pkg/sec/seccfg.go @@ -23,7 +23,7 @@ import ( "fmt" "sync/atomic" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/pkg/sec/secinit.go b/pkg/sec/secinit.go index 1817dcc6..4733936c 100644 --- a/pkg/sec/secinit.go +++ b/pkg/sec/secinit.go @@ -23,12 +23,12 @@ import ( "fmt" "sync" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/initmgr" - "juno/pkg/logging" - "juno/pkg/logging/cal" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/initmgr" + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/proto" ) const ( @@ -60,10 +60,10 @@ var ( type Flag uint8 /* - Two arguments required - arg 0: *Config - arg 1: uint8 bitmask flag - arg 2: isServerManager (optional) +Two arguments required +arg 0: *Config +arg 1: uint8 bitmask flag +arg 2: isServerManager (optional) */ func Initialize(args ...interface{}) (err error) { var cfg *Config diff --git a/pkg/sec/sslctx.go b/pkg/sec/sslctx.go index 1dfa0bde..0b4af3ed 100644 --- a/pkg/sec/sslctx.go +++ b/pkg/sec/sslctx.go @@ -28,6 +28,9 @@ import ( type ( Conn interface { GetStateString() string + GetTLSVersion() string + GetCipherName() string + DidResume() string IsServer() bool Handshake() error GetNetConn() net.Conn diff --git a/pkg/service/servermgr.go b/pkg/service/servermgr.go index 53f0bad6..d6182581 100644 --- a/pkg/service/servermgr.go +++ b/pkg/service/servermgr.go @@ -28,7 +28,7 @@ import ( "strings" "syscall" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type ( diff --git a/pkg/service/service.go b/pkg/service/service.go index 96629915..2dff0053 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -27,10 +27,10 @@ import ( "sync/atomic" "syscall" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/io" - "juno/pkg/logging/cal" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging/cal" ) type Service struct { diff --git a/pkg/service/svccfg.go b/pkg/service/svccfg.go index fc808cf5..b1971d01 100644 --- a/pkg/service/svccfg.go +++ b/pkg/service/svccfg.go @@ -24,8 +24,8 @@ import ( "strings" "time" - "juno/pkg/io" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" ) const ( diff --git a/pkg/stats/appnsstats.go b/pkg/stats/appnsstats.go index 44230817..9a2ffbe9 100644 --- a/pkg/stats/appnsstats.go +++ b/pkg/stats/appnsstats.go @@ -23,7 +23,7 @@ import ( "sync" "sync/atomic" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) const ( diff --git a/pkg/stats/redist/stats.go b/pkg/stats/redist/stats.go index 8674f88c..02a10b64 100644 --- a/pkg/stats/redist/stats.go +++ b/pkg/stats/redist/stats.go @@ -21,12 +21,13 @@ package redist import ( "fmt" - "juno/pkg/logging" - "juno/pkg/util" "strconv" "strings" "sync/atomic" "time" + + "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/util" ) var ( diff --git a/pkg/stats/sharedstats.go b/pkg/stats/sharedstats.go index 9d9d7e35..2563ec89 100644 --- a/pkg/stats/sharedstats.go +++ b/pkg/stats/sharedstats.go @@ -23,9 +23,9 @@ import ( "fmt" "os" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/shm" + "github.com/paypal/junodb/pkg/shm" ) type ( diff --git a/pkg/stats/statelog.go b/pkg/stats/statelog.go index 214cacd0..0a368273 100644 --- a/pkg/stats/statelog.go +++ b/pkg/stats/statelog.go @@ -28,9 +28,9 @@ import ( "time" "unsafe" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/proto" ) const ( diff --git a/pkg/udf/udfmgr_test.go b/pkg/udf/udfmgr_test.go index d1aca400..ed35ea09 100644 --- a/pkg/udf/udfmgr_test.go +++ b/pkg/udf/udfmgr_test.go @@ -21,7 +21,8 @@ package udf import ( "encoding/binary" - "juno/third_party/forked/golang/glog" + + "github.com/paypal/junodb/third_party/forked/golang/glog" "fmt" "testing" diff --git a/pkg/udf/udfplugin.go b/pkg/udf/udfplugin.go index 80a8e5a1..fcd3dc6e 100644 --- a/pkg/udf/udfplugin.go +++ b/pkg/udf/udfplugin.go @@ -26,7 +26,7 @@ import ( "plugin" "strings" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func loadOneUDFbyName(dir string, name string) (iudf IUDF, err error) { diff --git a/pkg/util/cmap.go b/pkg/util/cmap.go index 7d32db7e..762d5778 100644 --- a/pkg/util/cmap.go +++ b/pkg/util/cmap.go @@ -20,9 +20,10 @@ package util import ( - "github.com/spaolacci/murmur3" - "juno/third_party/forked/golang/glog" "sync" + + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/spaolacci/murmur3" ) type MapPartition struct { diff --git a/pkg/version/version.go b/pkg/version/version.go index 36f49f8c..028fb4fe 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -27,7 +27,7 @@ import ( "path/filepath" "runtime" - "juno/pkg/debug" + "github.com/paypal/junodb/pkg/debug" ) var ( diff --git a/script/deploy.sh b/script/deploy.sh index 27733dc3..4261eef6 100755 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -54,12 +54,7 @@ do $i/shutdown.sh fi - if [ $i != "junoclustercfg" ]; then - cp $BUILDTOP/package_config/package/${i}/script/shutdown.sh $i - cp $BUILDTOP/package_config/package/${i}/script/start.sh $i - fi - - cp $BUILDTOP/package_config/package/${i}/script/postinstall.sh $i + cp $BUILDTOP/package_config/package/${i}/script/*.sh $i cp $BUILDTOP/package_config/script/postuninstall.sh $i cp $BUILDTOP/package_config/script/logstate.sh $i cp $BUILDTOP/package_config/script/log.sh $i diff --git a/test/drv/bulkload/bulkload.go b/test/drv/bulkload/bulkload.go index 066d6c28..f7460e3f 100644 --- a/test/drv/bulkload/bulkload.go +++ b/test/drv/bulkload/bulkload.go @@ -21,7 +21,7 @@ // // Tool to create a set of random keys, which can be accessed by // [-get|-update|-set|-delete] in a subsequent command. -//================================================================= +// ================================================================= package main import ( @@ -35,10 +35,10 @@ import ( "strings" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/util" ) type CmdLine struct { diff --git a/test/drv/junoload/dbstats.go b/test/drv/junoload/dbstats.go index ed8b5f24..8cf414b8 100644 --- a/test/drv/junoload/dbstats.go +++ b/test/drv/junoload/dbstats.go @@ -22,10 +22,10 @@ package main import ( "fmt" - "juno/third_party/forked/golang/glog" - "juno/third_party/forked/tecbot/gorocksdb" + "github.com/paypal/junodb/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/tecbot/gorocksdb" - stor "juno/cmd/storageserv/storage/db" + stor "github.com/paypal/junodb/cmd/storageserv/storage/db" ) func PrintDbStats(name string) { diff --git a/test/drv/junoload/junoload.go b/test/drv/junoload/junoload.go index 9297f651..ea3f2aa9 100644 --- a/test/drv/junoload/junoload.go +++ b/test/drv/junoload/junoload.go @@ -24,20 +24,23 @@ import ( "fmt" "math/rand" "net/http" + _ "net/http/pprof" "os" + "strconv" "strings" "sync" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - "juno/pkg/client" - "juno/pkg/cmd" - "juno/pkg/logging/cal" - "juno/pkg/sec" - "juno/pkg/version" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cmd" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/pkg/version" ) type ( @@ -75,6 +78,8 @@ type ( logLevel string isVariable bool disableGetTTL bool + keys string + randomize bool } ) @@ -96,6 +101,7 @@ const ( func (d *SyncTestDriver) setDefaultConfig() { d.config.SetDefault() + d.config.Sec = sec.DefaultConfig d.config.Cal.Default() d.config.Cal.Poolname = "junoload" @@ -112,6 +118,9 @@ func (d *SyncTestDriver) setDefaultConfig() { d.config.StatOutputRate = kDefaultStatOutputRate d.config.isVariable = false d.config.disableGetTTL = false + d.config.sKey = -1 + d.config.eKey = -1 + d.config.randomize = false } func (d *SyncTestDriver) Init(name string, desc string) { @@ -141,6 +150,8 @@ func (d *SyncTestDriver) Init(name string, desc string) { d.StringOption(&d.cmdOpts.dbpath, "dbpath", "", "to display rocksdb stats") d.StringOption(&d.cmdOpts.logLevel, "log-level", "info", "specify log level") d.BoolOption(&d.cmdOpts.disableGetTTL, "disableGetTTL", false, "not use random ttl for get operation") + d.StringOption(&d.cmdOpts.keys, "keys", "", "key strange, separated with ,") + d.BoolOption(&d.cmdOpts.randomize, "r|randomize", false, "randomize, get/update/delete") t := &SyncTestDriver{} t.setDefaultConfig() @@ -160,7 +171,28 @@ func (d *SyncTestDriver) Init(name string, desc string) { d.AddExample(name+" -s 127.0.0.1:8080 -ssl", "\trun the driver with SSL") d.AddExample(name+" -c config.toml", "\trun the driver with options specified in config.toml") +} + +func parseKeys(key string) (start int, last int) { + var err error + list := strings.Split(key, ",") + start, err = strconv.Atoi(list[0]) + if err != nil { + glog.Exitf("%s", err) + } + if len(list) < 2 { + last = start + 1 + } else { + last, err = strconv.Atoi(list[1]) + if err != nil { + glog.Exitf("%s", err) + } + } + if start < 0 || last < 0 { + glog.Exitf("Negative range params are not allowed.") + } + return } func (d *SyncTestDriver) Parse(args []string) (err error) { @@ -235,6 +267,14 @@ func (d *SyncTestDriver) Parse(args []string) (err error) { d.config.HttpMonAddr = ":" + d.config.HttpMonAddr } + if d.cmdOpts.keys != "" { + start, end := parseKeys(d.cmdOpts.keys) + d.config.sKey = int64(start) + d.config.eKey = int64(end) + } + + d.config.randomize = d.cmdOpts.randomize + d.config.Cal.Default() if d.config.Cal.Enabled { @@ -303,6 +343,10 @@ func (d *SyncTestDriver) Exec() { var wg sync.WaitGroup chDone := make(chan bool) + var numRunningExecutors util.AtomicCounter + numRunningExecutors.Reset() + numRunningExecutors.Add(int32(d.config.NumExecutor)) + if d.config.NumExecutor > 0 { wg.Add(1) go func() { @@ -322,9 +366,14 @@ func (d *SyncTestDriver) Exec() { case <-ticker.C: d.movingStats.PrettyPrint(os.Stdout) d.movingStats.Reset() + if numRunningExecutors.Get() == 0 { + timer.Stop() + ticker.Stop() + close(chDone) + break loop + } } } - }() } else { glog.Errorf("number of executor specified is zero") @@ -333,15 +382,17 @@ func (d *SyncTestDriver) Exec() { d.tmStart = time.Now() d.stats.Init() d.movingStats.Init() + var start int = -1 + var end int = -1 + for i := 0; i < d.config.NumExecutor; i++ { - size := d.cmdOpts.numKeys / 2 - num := size / d.config.NumExecutor - offGet := i*num + size + if d.config.sKey >= 0 && d.config.eKey > d.config.sKey { + range_size := (d.config.eKey - d.config.sKey + int64(d.config.NumExecutor-1)) / int64(d.config.NumExecutor) - if size > MaxDeletes { - size = MaxDeletes + start = i*int(range_size) + int(d.config.sKey) + end = start + int(range_size) - 1 //pad } - offDel := i * (size / d.config.NumExecutor) + //fmt.Printf("s=%d, e=%d\n", start, end) cli, err := client.New(d.config.Config) if err != nil { glog.Error(err) @@ -350,15 +401,18 @@ func (d *SyncTestDriver) Exec() { eng := &TestEngine{ rdgen: d.randgen, recStore: RecordStore{ - numKeys: num, - offsetDel: offDel, - offsetGet: offGet}, + nextKey: int(start), + sKey: int(start), + eKey: int(end), + randomize: d.config.randomize, + }, reqSequence: d.reqSequence, // chDone: chDone, client: cli, stats: &d.stats, movingStats: &d.movingStats, numReqPerSecond: d.config.NumReqPerSecond, + numRunningExec: &numRunningExecutors, } eng.Init() wg.Add(1) diff --git a/test/drv/junoload/tdscfg.go b/test/drv/junoload/tdscfg.go index 46fb27e6..2880f270 100644 --- a/test/drv/junoload/tdscfg.go +++ b/test/drv/junoload/tdscfg.go @@ -20,9 +20,9 @@ package main import ( - "juno/pkg/client" - "juno/pkg/logging/cal/config" - "juno/pkg/sec" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/sec" ) type ( @@ -43,5 +43,8 @@ type ( StatOutputRate int isVariable bool disableGetTTL bool + sKey int64 + eKey int64 + randomize bool } ) diff --git a/test/drv/junoload/tsteng.go b/test/drv/junoload/tsteng.go index a9970bfc..8cdd77f8 100644 --- a/test/drv/junoload/tsteng.go +++ b/test/drv/junoload/tsteng.go @@ -16,20 +16,22 @@ // See the License for the specific language governing permissions and // limitations under the License. // - package main import ( "encoding/binary" + "errors" "fmt" "math" "math/rand" "sync" "time" - "juno/pkg/client" + "github.com/paypal/junodb/pkg/client" + + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/third_party/forked/golang/glog" + "juno/pkg/util" uuid "github.com/satori/go.uuid" ) @@ -43,7 +45,7 @@ const ( kNumRequestTypes ) -const MaxDeletes = 10000 +var ErrNoMoreKeys = errors.New("no more keys") type ( RequestType uint8 @@ -53,14 +55,11 @@ type ( } RecordStore struct { - records []Record - // Used for preloaded keys - numKeys int - currGet int - nextDelete int - offsetDel int - offsetGet int - LastDelete bool + records []Record + sKey int + eKey int + nextKey int + randomize bool } TestEngine struct { @@ -73,6 +72,7 @@ type ( stats *Statistics movingStats *Statistics numReqPerSecond int + numRunningExec *util.AtomicCounter } InvokeFunc func() error ) @@ -128,27 +128,35 @@ func (r *Record) isExpired() bool { } func (s *RecordStore) Add(rec Record) { - if s.numKeys > 0 { + if s.isKeyRange() { return } + s.records = append(s.records, rec) } func (s *RecordStore) display() { - glog.Infof("numKeys=%d currGet=%d nextDelete=%d offsetDel=%d offsetGet=%d", - s.numKeys, s.currGet, s.nextDelete, s.offsetDel, s.offsetGet) + /* + glog.Infof("numKeys=%d currGet=%d nextDelete=%d offsetDel=%d offsetGet=%d", + s.numKeys, s.currGet, s.nextDelete, s.offsetDel, s.offsetGet)*/ } func (s *RecordStore) takeRecord() (rec Record, err error) { - if s.numKeys > 0 { // preloaded keys - rec = Record{ - key: NewRandomKey(s.offsetDel + s.nextDelete), + if s.isKeyRange() { + var key_id int + if s.randomize { + key_id = s.sKey + rand.Intn(s.eKey-s.sKey+1) + } else { + if s.nextKey > s.eKey { + err = ErrNoMoreKeys + return + } + key_id = s.nextKey + s.nextKey++ } - if s.endOfDelete() { - err = fmt.Errorf("no more record for destroy") - return + rec = Record{ + key: NewRandomKey(key_id), } - s.nextDelete++ return } @@ -164,17 +172,23 @@ func (s *RecordStore) takeRecord() (rec Record, err error) { } func (s *RecordStore) getRecord() (rec Record, err error) { - if s.numKeys > 0 { // preloaded keys - count := s.numKeys - if s.numKeys >= MaxDeletes { - count = s.numKeys >> 2 + if s.isKeyRange() { + var key_id int + if s.randomize { + key_id = s.sKey + rand.Intn(s.eKey-s.sKey+1) + } else { + if s.nextKey > s.eKey { + err = ErrNoMoreKeys + return + } + key_id = s.nextKey + s.nextKey++ } - k := expRand(count) - s.currGet = k rec = Record{ - key: NewRandomKey(s.offsetGet + k), + key: NewRandomKey(key_id), } + return } @@ -193,32 +207,26 @@ func (s *RecordStore) getRecord() (rec Record, err error) { } func (s *RecordStore) empty() bool { - return len(s.records) == 0 && s.numKeys == 0 -} - -func (s *RecordStore) endOfDelete() bool { - return s.numKeys > 0 && - (s.nextDelete >= s.numKeys || s.nextDelete >= MaxDeletes) + return len(s.records) == 0 && s.isKeyRange() == false } func (s *RecordStore) Get() (rec Record, err error) { for !s.empty() { rec, err = s.getRecord() - if err == nil { - return - } + return } err = fmt.Errorf("no record") return } func (s *RecordStore) Take() (rec Record, err error) { - for !s.empty() && !s.endOfDelete() { + if s.isKeyRange() { + return s.takeRecord() + } + + if !s.empty() { rec, err = s.takeRecord() - if err == nil && !rec.isExpired() { - if s.endOfDelete() { - s.LastDelete = true - } + if err == nil { return } } @@ -226,6 +234,23 @@ func (s *RecordStore) Take() (rec Record, err error) { return } +func (s *RecordStore) getNextKey() (key []byte) { + if s.sKey == -1 { + key = newTestKey() + } else { + if s.nextKey > s.eKey { + return nil + } + key = NewRandomKey(s.nextKey) + s.nextKey++ + } + return +} + +func (s *RecordStore) isKeyRange() bool { + return s.sKey > -1 +} + func (e *TestEngine) Init() { e.invokeFuncs = make([]InvokeFunc, kNumRequestTypes) e.invokeFuncs[kRequestTypeCreate] = e.invokeCreate @@ -235,70 +260,35 @@ func (e *TestEngine) Init() { e.invokeFuncs[kRequestTypeDestroy] = e.invokeDestroy } -func (e *TestEngine) restoreData() { - if e.recStore.numKeys <= 0 || e.recStore.nextDelete <= 0 { - return - } - - count := e.recStore.nextDelete - - // Add back deleted keys - glog.Infof("Add back deleted keys: count=%d", count) - for i := 0; i < count; i++ { - - now := time.Now() - - key := NewRandomKey(e.recStore.offsetDel + i) - _, err := e.client.Create(key, e.rdgen.createPayload()) - tm := time.Since(now) - - e.stats.Put(kRequestTypeCreate, tm, err) - e.movingStats.Put(kRequestTypeCreate, tm, err) - if err != nil { - glog.Errorf("%s error: %s", kRequestTypeCreate.String(), err) - e.recStore.display() - } - } -} - func (e *TestEngine) Run(wg *sync.WaitGroup, chDone <-chan bool) { defer wg.Done() + defer e.numRunningExec.Add(-1) startTime := time.Now() var numreq int = 0 errCount := 0 + for { for _, item := range e.reqSequence.items { - if e.recStore.numKeys > 0 && - item.reqType == kRequestTypeCreate { - continue - } for i := 0; i < item.numRequests; i++ { select { case <-chDone: - e.restoreData() return default: now := time.Now() err := e.invoke(item.reqType) tm := time.Since(now) - if item.reqType == kRequestTypeDestroy && - e.recStore.endOfDelete() { - if e.recStore.LastDelete { - e.recStore.LastDelete = false - } else { - continue - } + if errors.Is(err, ErrNoMoreKeys) { + return } + e.stats.Put(item.reqType, tm, err) e.movingStats.Put(item.reqType, tm, err) if err != nil { glog.Errorf("%s error: %s", item.reqType.String(), err) - if e.recStore.numKeys > 0 { - e.recStore.display() - errCount++ - if errCount > 100 { - return - } + e.recStore.display() + errCount++ + if errCount > 100 { + //return } } diff := now.Sub(startTime) @@ -355,10 +345,13 @@ func (e *TestEngine) checkSpeedForVariableTp(now time.Time, numReq int, startTim } func (e *TestEngine) invokeCreate() (err error) { - if e.recStore.numKeys > 0 { + + key := e.recStore.getNextKey() + if key == nil { + err = ErrNoMoreKeys return } - key := newTestKey() + var ctx client.IContext if ctx, err = e.client.Create(key, e.rdgen.createPayload(), client.WithTTL(e.rdgen.getTTL())); err == nil { @@ -405,9 +398,6 @@ func (e *TestEngine) invokeSet() (err error) { func (e *TestEngine) invokeDestroy() (err error) { var rec Record - if e.recStore.endOfDelete() { - return nil - } if rec, err = e.recStore.Take(); err == nil { err = e.client.Destroy(rec.key) } diff --git a/test/fakess/config.go b/test/fakess/config.go index f6169bca..39521e64 100644 --- a/test/fakess/config.go +++ b/test/fakess/config.go @@ -1,23 +1,24 @@ -// +// // Copyright 2023 PayPal Inc. -// +// // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// - -// +build +// + +//go:build ignore +// +build ignore package main @@ -25,13 +26,13 @@ import ( "math" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - "juno/pkg/io" - cal "juno/pkg/logging/cal/config" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + cal "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/util" ) var Conf = Config{ diff --git a/test/fakess/main.go b/test/fakess/main.go index cf0c2eba..fd5ef392 100644 --- a/test/fakess/main.go +++ b/test/fakess/main.go @@ -1,34 +1,36 @@ -// +// // Copyright 2023 PayPal Inc. -// +// // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// - -// +build +// + +//go:build ignore +// +build ignore package main import ( "flag" - "juno/pkg/logging/cal" - "juno/pkg/service" "net" "strconv" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/service" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/test/fakess/requesthandler.go b/test/fakess/requesthandler.go index ebc03ab3..837949b5 100644 --- a/test/fakess/requesthandler.go +++ b/test/fakess/requesthandler.go @@ -1,34 +1,36 @@ -// +// // Copyright 2023 PayPal Inc. -// +// // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// - -// +build +// + +//go:build ignore +// +build ignore package main import ( - "juno/pkg/io" - _ "juno/pkg/logging" - "juno/pkg/proto" "math/rand" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/io" + _ "github.com/paypal/junodb/pkg/logging" + "github.com/paypal/junodb/pkg/proto" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) //type IRequestHandler interface { diff --git a/test/functest/create_test.go b/test/functest/create_test.go index 1e4e261a..206539e0 100644 --- a/test/functest/create_test.go +++ b/test/functest/create_test.go @@ -24,11 +24,11 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/pkg/util" - "juno/test/testutil" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/test/testutil" ) /*************************************************** diff --git a/test/functest/delete_test.go b/test/functest/delete_test.go index 0b0dfb6b..6ebb9603 100644 --- a/test/functest/delete_test.go +++ b/test/functest/delete_test.go @@ -21,10 +21,11 @@ package functest import ( // "encoding/hex" - "juno/pkg/client" - "juno/test/testutil" "testing" "time" + + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/test/testutil" ) /************************************************************************ diff --git a/test/functest/get_test.go b/test/functest/get_test.go index 1a8640fa..2013fd13 100644 --- a/test/functest/get_test.go +++ b/test/functest/get_test.go @@ -20,13 +20,14 @@ package functest import ( - "juno/pkg/client" - "juno/pkg/util" - "juno/test/testutil" "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/test/testutil" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) /*********************************************************************** diff --git a/test/functest/set_test.go b/test/functest/set_test.go index fc333ef9..b7133914 100644 --- a/test/functest/set_test.go +++ b/test/functest/set_test.go @@ -20,13 +20,14 @@ package functest import ( - "juno/pkg/client" - "juno/test/testutil" "strconv" "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/test/testutil" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) /************************************************* diff --git a/test/functest/setup_test.go b/test/functest/setup_test.go index e5244527..27dd384e 100644 --- a/test/functest/setup_test.go +++ b/test/functest/setup_test.go @@ -30,19 +30,19 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" "github.com/BurntSushi/toml" - "juno/cmd/proxy/config" - "juno/pkg/client" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/io" - "juno/pkg/logging/cal" - "juno/pkg/sec" - "juno/pkg/util" - "juno/test/testutil/server" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/logging/cal" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/test/testutil/server" ) var testConfig = server.ClusterConfig{ diff --git a/test/functest/update_test.go b/test/functest/update_test.go index 28697e15..bbc4eed4 100644 --- a/test/functest/update_test.go +++ b/test/functest/update_test.go @@ -24,10 +24,10 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/test/testutil" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/test/testutil" ) /**************************************************** diff --git a/test/mockss/mockss.go b/test/mockss/mockss.go index e1d87588..bc22f2fb 100644 --- a/test/mockss/mockss.go +++ b/test/mockss/mockss.go @@ -22,8 +22,9 @@ package main import ( "flag" "fmt" - "juno/test/testutil/mock" - "juno/third_party/forked/golang/glog" + + "github.com/paypal/junodb/test/testutil/mock" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) func main() { diff --git a/test/testutil/log/frwk/frwk.go b/test/testutil/log/frwk/frwk.go index 63b55fae..55570efa 100644 --- a/test/testutil/log/frwk/frwk.go +++ b/test/testutil/log/frwk/frwk.go @@ -20,7 +20,7 @@ package frwk import ( - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var ( diff --git a/test/testutil/mock/client.go b/test/testutil/mock/client.go index 9cedae1e..189ab15c 100644 --- a/test/testutil/mock/client.go +++ b/test/testutil/mock/client.go @@ -26,11 +26,11 @@ import ( "net" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/pkg/cluster" - "juno/pkg/proto" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/proto" ) type MockClient struct { diff --git a/test/testutil/mock/common.go b/test/testutil/mock/common.go index 1d6184ed..9d203733 100644 --- a/test/testutil/mock/common.go +++ b/test/testutil/mock/common.go @@ -26,7 +26,7 @@ import ( "testing" "time" - . "juno/pkg/proto" + . "github.com/paypal/junodb/pkg/proto" ) const ( diff --git a/test/testutil/mock/config.go b/test/testutil/mock/config.go index 93a98c75..dcd03d5c 100644 --- a/test/testutil/mock/config.go +++ b/test/testutil/mock/config.go @@ -23,9 +23,9 @@ import ( "math" "time" - "juno/pkg/io" - "juno/pkg/service" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/util" ) type SSConfig struct { diff --git a/test/testutil/mock/ssreqhandler.go b/test/testutil/mock/ssreqhandler.go index c5942b06..40d4d86a 100644 --- a/test/testutil/mock/ssreqhandler.go +++ b/test/testutil/mock/ssreqhandler.go @@ -25,13 +25,13 @@ import ( "sync" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - // "juno/cmd/proxy/handler" - "juno/pkg/io" - "juno/pkg/proto" - "juno/pkg/service" - "juno/pkg/util" + // "github.com/paypal/junodb/cmd/proxy/handler" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/pkg/util" ) var _ io.IRequestHandler = (*RequestHandler)(nil) diff --git a/test/testutil/server/cluster.go b/test/testutil/server/cluster.go index 4467ef7e..1d9d287b 100644 --- a/test/testutil/server/cluster.go +++ b/test/testutil/server/cluster.go @@ -31,16 +31,16 @@ import ( "syscall" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/handler" - "juno/cmd/proxy/stats" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/net/netutil" - "juno/pkg/util" - "juno/test/testutil/log/frwk" - "juno/test/testutil/mock" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/handler" + "github.com/paypal/junodb/cmd/proxy/stats" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/net/netutil" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/test/testutil/log/frwk" + "github.com/paypal/junodb/test/testutil/mock" ) type ICluster interface { diff --git a/test/testutil/server/config.go b/test/testutil/server/config.go index dde5a67f..9899ac15 100644 --- a/test/testutil/server/config.go +++ b/test/testutil/server/config.go @@ -20,11 +20,11 @@ package server import ( - "juno/cmd/proxy/config" - "juno/pkg/io" - cal "juno/pkg/logging/cal/config" - "juno/pkg/sec" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/io" + cal "github.com/paypal/junodb/pkg/logging/cal/config" + "github.com/paypal/junodb/pkg/sec" + "github.com/paypal/junodb/pkg/util" ) type ServerDef struct { diff --git a/test/testutil/server/inprocsrv.go b/test/testutil/server/inprocsrv.go index 69ef735b..217c14d7 100644 --- a/test/testutil/server/inprocsrv.go +++ b/test/testutil/server/inprocsrv.go @@ -23,10 +23,10 @@ import ( "fmt" "sync" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/service" - "juno/test/testutil/log/frwk" + "github.com/paypal/junodb/pkg/service" + "github.com/paypal/junodb/test/testutil/log/frwk" ) var _ IServer = (*InProcessServer)(nil) diff --git a/test/testutil/server/server.go b/test/testutil/server/server.go index 88871815..9f1c0c10 100644 --- a/test/testutil/server/server.go +++ b/test/testutil/server/server.go @@ -22,7 +22,6 @@ package server import ( "fmt" pkgio "io" - "juno/third_party/forked/golang/glog" "net" "net/http" "os" @@ -31,11 +30,13 @@ import ( "strings" "time" - "juno/internal/cli" - "juno/pkg/io" - "juno/pkg/net/netutil" - "juno/pkg/proto" - "juno/test/testutil/log/frwk" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/net/netutil" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil/log/frwk" ) const ( diff --git a/test/testutil/server/ssnode.go b/test/testutil/server/ssnode.go index dcd2994a..105d0469 100644 --- a/test/testutil/server/ssnode.go +++ b/test/testutil/server/ssnode.go @@ -23,10 +23,10 @@ import ( "fmt" "net" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/test/testutil/ssclient" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/test/testutil/ssclient" ) type SSNode struct { diff --git a/test/testutil/ssclient/advssclient.go b/test/testutil/ssclient/advssclient.go index 876e69e7..ffe0abfe 100644 --- a/test/testutil/ssclient/advssclient.go +++ b/test/testutil/ssclient/advssclient.go @@ -24,11 +24,11 @@ import ( "net" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/pkg/etcd" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type Config struct { diff --git a/test/testutil/ssclient/ssclient.go b/test/testutil/ssclient/ssclient.go index 273704e0..a5a4b82a 100644 --- a/test/testutil/ssclient/ssclient.go +++ b/test/testutil/ssclient/ssclient.go @@ -24,12 +24,12 @@ import ( "io" "net" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/internal/cli" - "juno/pkg/client" - "juno/pkg/proto" - "juno/pkg/util" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/pkg/util" ) type Record struct { diff --git a/test/testutil/testhelper.go b/test/testutil/testhelper.go index 537e36ee..7ac9b6cc 100644 --- a/test/testutil/testhelper.go +++ b/test/testutil/testhelper.go @@ -34,17 +34,17 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" - - "juno/cmd/proxy/config" - "juno/internal/cli" - "juno/pkg/client" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/io" - "juno/pkg/util" - "juno/test/testutil/mock" - "juno/test/testutil/server" + "github.com/paypal/junodb/third_party/forked/golang/glog" + + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/internal/cli" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" + "github.com/paypal/junodb/test/testutil/mock" + "github.com/paypal/junodb/test/testutil/server" ) type KVMap map[string]string @@ -227,7 +227,7 @@ func ApproxEqual(v1 uint32, v2 uint32, epsilon uint32) bool { return (v2 - v1) <= epsilon } -//This function has to be called right after getting RecordInfo +// This function has to be called right after getting RecordInfo func VerifyRecordInfo(recInfo client.IContext, ver uint32, ttl uint32, creationTime uint32) error { if recInfo == nil { return fmt.Errorf("nil recInfo") @@ -958,7 +958,7 @@ func LoadInitConfig(hostip string) { time.Sleep(3 * time.Second) } -//temporally create redist info +// temporally create redist info func UpdateRedistConfig(t *testing.T, hostip string, connNo string, configFile string) { var cmd string var cmd1 string @@ -989,7 +989,7 @@ func UpdateRedistConfig(t *testing.T, hostip string, connNo string, configFile s time.Sleep(3 * time.Second) } -//start redist +// start redist func StartRedistConfig(t *testing.T, hostip string, markdown string) { var localIp bool = false var cmd string @@ -1009,7 +1009,7 @@ func StartRedistConfig(t *testing.T, hostip string, markdown string) { } } -//start auto redistribution +// start auto redistribution func StartAutoRedistConfig(t *testing.T, hostip string, markdown string) { var localIp bool = false var cmd string @@ -1027,7 +1027,7 @@ func StartAutoRedistConfig(t *testing.T, hostip string, markdown string) { exec.Command("bash", "-c", cmd).Output() } -//temporally check forward finish, all zones are snapshot_finish +// temporally check forward finish, all zones are snapshot_finish func FinishForwardCheck(t *testing.T, hostip string) { var cmd string if ResolveHostIp() != hostip { @@ -1044,7 +1044,7 @@ func FinishForwardCheck(t *testing.T, hostip string) { } } -//resume the aborted redistribution +// resume the aborted redistribution func ResumeAbortedReq(t *testing.T, hostip string) { var cmd string if ResolveHostIp() != hostip { @@ -1058,7 +1058,7 @@ func ResumeAbortedReq(t *testing.T, hostip string) { exec.Command("bash", "-c", cmd).Output() } -//commit the new change +// commit the new change func FinalizeConfig(t *testing.T, hostip string) { var cmd string if ResolveHostIp() != hostip { @@ -1164,7 +1164,7 @@ func ReInitializeCluster(config server.ClusterConfig) (c *server.Cluster) { return server.NewClusterWithConfig(&config) } -//This definitely will be deleted as it's a temporally workaround for shutdown issue +// This definitely will be deleted as it's a temporally workaround for shutdown issue func SSShutdown(hostip string, secondhost bool) { var cmd string if ResolveHostIp() != hostip { diff --git a/test/testutil/tmkeeper.go b/test/testutil/tmkeeper.go index ee269605..622a0171 100644 --- a/test/testutil/tmkeeper.go +++ b/test/testutil/tmkeeper.go @@ -22,7 +22,7 @@ package testutil import ( "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" ) type timeKeeper struct { diff --git a/test/unittest/create_test.go b/test/unittest/create_test.go index 7a78105f..d49974f4 100644 --- a/test/unittest/create_test.go +++ b/test/unittest/create_test.go @@ -21,14 +21,15 @@ package unittest import ( "fmt" - "juno/pkg/client" - "juno/pkg/proto" - "juno/test/testutil" - "juno/test/testutil/mock" "strconv" "testing" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" + "github.com/paypal/junodb/test/testutil/mock" + + "github.com/paypal/junodb/third_party/forked/golang/glog" ) var createStatusArray [7]uint8 diff --git a/test/unittest/destroy_test.go b/test/unittest/destroy_test.go index baf68e68..f43b7854 100644 --- a/test/unittest/destroy_test.go +++ b/test/unittest/destroy_test.go @@ -1,29 +1,28 @@ +// Copyright 2023 PayPal Inc. // -// Copyright 2023 PayPal Inc. +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at // -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// http://www.apache.org/licenses/LICENSE-2.0 // +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. package unittest import ( - "juno/pkg/client" - "juno/pkg/proto" - "juno/test/testutil" - "juno/test/testutil/mock" "testing" + + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" + "github.com/paypal/junodb/test/testutil/mock" ) var prepareDeleteArr [4]uint8 diff --git a/test/unittest/get_test.go b/test/unittest/get_test.go index de355260..3235a8b9 100644 --- a/test/unittest/get_test.go +++ b/test/unittest/get_test.go @@ -20,11 +20,12 @@ package unittest import ( - "juno/pkg/client" - "juno/pkg/proto" - "juno/test/testutil" - "juno/test/testutil/mock" "testing" + + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" + "github.com/paypal/junodb/test/testutil/mock" ) var getStatusArray [5]uint8 diff --git a/test/unittest/set_test.go b/test/unittest/set_test.go index 2981117b..b961176e 100644 --- a/test/unittest/set_test.go +++ b/test/unittest/set_test.go @@ -20,11 +20,12 @@ package unittest import ( - "juno/pkg/client" - "juno/pkg/proto" - "juno/test/testutil" - "juno/test/testutil/mock" "testing" + + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" + "github.com/paypal/junodb/test/testutil/mock" ) var setPrepareArray [7]uint8 diff --git a/test/unittest/setup_test.go b/test/unittest/setup_test.go index f7541e9a..a7881275 100644 --- a/test/unittest/setup_test.go +++ b/test/unittest/setup_test.go @@ -28,17 +28,17 @@ import ( "testing" "time" - "juno/third_party/forked/golang/glog" + "github.com/paypal/junodb/third_party/forked/golang/glog" - "juno/cmd/proxy/config" - "juno/pkg/client" - "juno/pkg/cluster" - "juno/pkg/etcd" - "juno/pkg/io" - "juno/pkg/util" + "github.com/paypal/junodb/cmd/proxy/config" + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/cluster" + "github.com/paypal/junodb/pkg/etcd" + "github.com/paypal/junodb/pkg/io" + "github.com/paypal/junodb/pkg/util" - "juno/test/testutil/mock" - "juno/test/testutil/server" + "github.com/paypal/junodb/test/testutil/mock" + "github.com/paypal/junodb/test/testutil/server" ) var testConfig = server.ClusterConfig{ diff --git a/test/unittest/update_test.go b/test/unittest/update_test.go index 4f74b5e6..d8b0ef4f 100644 --- a/test/unittest/update_test.go +++ b/test/unittest/update_test.go @@ -20,12 +20,13 @@ package unittest import ( - //"juno/third_party/forked/golang/glog" - "juno/pkg/client" - "juno/pkg/proto" - "juno/test/testutil" - "juno/test/testutil/mock" + //"github.com/paypal/junodb/third_party/forked/golang/glog" "testing" + + "github.com/paypal/junodb/pkg/client" + "github.com/paypal/junodb/pkg/proto" + "github.com/paypal/junodb/test/testutil" + "github.com/paypal/junodb/test/testutil/mock" ) var updatePrepareArray [6]uint8