Class: Ladle::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/ladle/server.rb

Overview

Controller for Ladle’s core feature, the embedded LDAP server.

Defined Under Namespace

Classes: ApacheDSController, LogStreamWatcher

Constant Summary collapse

ERROR_LEVELS =
%w(ERROR WARN)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Server

Returns a new instance of Server.

Parameters:

  • opts (Hash) (defaults to: {})

    the options for the server

Options Hash (opts):

  • :port (Fixnum) — default: 3897

    The port to serve from.

  • :ldif (String) — default: {path to the gem}/lib/ladle/default.ldif

    The filename of the LDIF-formatted data to use for this server. If provide your own data, be sure to set the :domain option to match.

  • :domain (String) — default: "dc=example,dc=org"

    the domain for the data provided in the :ldif option.

  • :allow_anonymous (Boolean) — default: true

    whether anonymous users will be able to query the server.

  • :verbose (Boolean) — default: false

    if true, detailed information about the execution of the server will be printed to standard error.

  • :quiet (Boolean) — default: false

    if true no information about regular execution will be printed. Error information will still be printed. This trumps ‘:verbose`.

  • :timeout (Fixnum) — default: 60

    the amount of time to wait (seconds) for the server process to start before giving up.

  • :tmpdir (String) — default: ENV['TMPDIR'] or ENV['TEMPDIR']

    the temporary directory to use for the server’s files. If not guessable from the environment, it must be specified. It must already exist.

  • :java_bin (String) — default: "java" or File.join(ENV["JAVA_HOME"], "bin", "java")

    the java executable to use to run the embedded server.

  • :custom_schemas (String, Array<String>) — default: []

    the names of classes representing custom schemas to use in the server.

  • :additional_classpath (String, Array<String>) — default: []

    entries to add to the classpath for the embedded server.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ladle/server.rb', line 86

def initialize(opts={})
  @port = opts[:port] || 3897
  @domain = opts[:domain] || "dc=example,dc=org"
  @ldif = opts[:ldif] || File.expand_path("../default.ldif", __FILE__)
  @allow_anonymous = opts[:allow_anonymous].nil? ? true : opts[:allow_anonymous]
  @quiet = opts[:quiet]
  @verbose = opts[:verbose]
  @timeout = opts[:timeout] || 60
  @tmpdir = opts[:tmpdir] || ENV['TEMPDIR'] || Dir.tmpdir
  @java_bin = opts[:java_bin] ||
    (ENV['JAVA_HOME'] ? File.join(ENV['JAVA_HOME'], "bin", "java") : "java")
  @custom_schemas = opts[:custom_schemas] ? [*opts[:custom_schemas]] : []
  @additional_classpath =
    opts[:additional_classpath] ? [*opts[:additional_classpath]] : []

  # Additional arguments that can be passed to the java server
  # process.  Used for testing only, so not documented.
  @additional_args = opts[:more_args] || []

  unless @domain =~ /^dc=/i
    raise "The domain component must start with 'dc='.  '#{@domain}' does not."
  end

  unless File.directory?(tmpdir)
    raise "Tmpdir #{tmpdir.inspect} does not exist."
  end

  unless File.readable?(@ldif)
    raise "Cannot read specified LDIF file #{@ldif}."
  end
end

Instance Attribute Details

#additional_classpathArray<String> (readonly)

Any additional entries to add to the classpath for the server, e.g., jars containing custom schemas.

Returns:

  • (Array<String>)


53
54
55
# File 'lib/ladle/server.rb', line 53

def additional_classpath
  @additional_classpath
end

#custom_schemasArray<String> (readonly)

Any custom schemas to use with the server.

Returns:

  • (Array<String>)


47
48
49
# File 'lib/ladle/server.rb', line 47

def custom_schemas
  @custom_schemas
end

#domainString (readonly)

The domain for the served data.

Returns:

  • (String)


18
19
20
# File 'lib/ladle/server.rb', line 18

def domain
  @domain
end

#java_binString (readonly)

The java executable to use to run the embedded server.

Returns:

  • (String)


42
43
44
# File 'lib/ladle/server.rb', line 42

def java_bin
  @java_bin
end

#ldifString (readonly)

The filename of the LDIF data loaded into this server before it started.

Returns:

  • (String)


24
25
26
# File 'lib/ladle/server.rb', line 24

def ldif
  @ldif
end

#portFixnum (readonly)

The port from which this server will be available.

Returns:

  • (Fixnum)


13
14
15
# File 'lib/ladle/server.rb', line 13

def port
  @port
end

#timeoutFixnum (readonly)

The time to wait for the server to start up before giving up (seconds).

Returns:

  • (Fixnum)


30
31
32
# File 'lib/ladle/server.rb', line 30

def timeout
  @timeout
end

#tmpdirString (readonly)

The base directory into which the server should write its temporary files. Ladle will create a directory under this path on startup and remove it on shutdown.

Returns:

  • (String)


37
38
39
# File 'lib/ladle/server.rb', line 37

def tmpdir
  @tmpdir
end

Instance Method Details

#allow_anonymous?Boolean

Whether anonymous users will be allowed access to the server once it is running.

Returns:

  • (Boolean)


224
225
226
# File 'lib/ladle/server.rb', line 224

def allow_anonymous?
  @allow_anonymous
end

#log(msg) ⇒ Object

Visible for collaborators.



188
189
190
# File 'lib/ladle/server.rb', line 188

def log(msg)
  $stderr.puts(msg) unless quiet?
end

#log_error(msg) ⇒ Object

Visible for collaborators.



181
182
183
# File 'lib/ladle/server.rb', line 181

def log_error(msg)
  $stderr.puts(msg)
end

#quiet?Boolean

If the controller will print anything about what it is doing to stderr. If this is true, all non-error output will be supressed. This value trumps #verbose?.

Returns:

  • (Boolean)


205
206
207
# File 'lib/ladle/server.rb', line 205

def quiet?
  @quiet
end

#startServer

Starts up the server in a separate process. This method will not return until the server is listening on the specified port. The same Ladle::Server instance can be started and stopped multiple times, but the runs will be independent.

Returns:



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/ladle/server.rb', line 125

def start
  return if @running
  log "Starting server on #{port}"
  trace "- Server command: #{server_cmd.inspect}"
  java_in, java_out, java_err = create_process(*server_cmd).popen
  @running = true
  trace "- Started subprocess #{process.pid}"

  @log_watcher = LogStreamWatcher.new(java_err, self)
  @log_watcher.start
  @controller = ApacheDSController.new(java_in, java_out, self)
  @controller.start

  # TODO: perhaps this busywait can be replaced with select?
  trace "- Waiting for server to start"
  started_waiting = Time.now
  until @controller.started? || @controller.error? || Time.now > started_waiting + timeout
    trace "  . waited #{Time.now - started_waiting} seconds"
    sleep 0.5
  end
  trace "- Stopped waiting after #{Time.now - started_waiting} seconds"

  if @controller.error?
    self.stop
    trace "! Subprocess error (see above)"
    raise "LDAP server failed to start"
  elsif !@controller.started?
    self.stop
    trace "! Timed out"
    raise "LDAP server startup did not complete within #{timeout} seconds"
  end

  trace "- Server started successfully"
  at_exit { stop }

  self
end

#stopObject

Stops the server that was started with #start.



165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/ladle/server.rb', line 165

def stop
  return if !@running
  log "Stopping server on #{port}"
  trace "- Stopping server process"
  @controller.stop if @controller

  trace "- Signalling server process to stop if not already stopped"
  process.stop_gracefully
  process.wait

  @running = false
end

#trace(msg) ⇒ Object

Visible for collaborators.



195
196
197
# File 'lib/ladle/server.rb', line 195

def trace(msg)
  $stderr.puts(msg) if verbose? && !quiet?
end

#verbose?Boolean

Whether the controller will print detailed information about what it is doing to stderr. This includes information from the embedded ApacheDS instance.

Returns:

  • (Boolean)


215
216
217
# File 'lib/ladle/server.rb', line 215

def verbose?
  @verbose
end