public abstract class IfsServer extends Server implements TimerContext
Subclassing IfsServer provides an easier approach to creating a server than subclassing Server itself. IfsServer provides default implementations for many of the methods required, offers a set of tools useful in writing a server, and simplifies development of a thread-safe server.
The most basic server can be created by subclassing IfsServer,
providing a zero-argument constructor, and implementing the
run
method.
More sophisticated servers provide implementations for the following life-cycle methods:
initialize
:
operations performed once, when the server is loaded on the node
preRun
:
operations performed each time the server is started, immediately
before run
is called
run
:
operations performed when the server is running
postRun
:
operations performed each time the server is stopped, immediately
after run
returns
dispose
:
operations performed once, when the server is unloaded from the node
Servers can obtain information on their runtime environment by calling the following methods:
getName
:
gets the name of the server
getParameterTable
:
gets the configuration parameters for the server
getServiceName
and getService
:
gets the service against which the server should operate
A server can publish dynamic properties regarding its operation (for example, the current number of connections). These properties can be readonly (viewed using CM SDK Manager) or writeable (viewed and set using CM SDK Manager).
A timer can be started to generate periodic "timer expiration" requests. This is useful for servers that perform some task at defined intervals.
A server can establish a "default" LibrarySession against which it
operates. If a server uses more than one LibrarySession, it can call
getCredential
to obtain a credential for any CM SDK user.
A typical server may respond to administrative commands (such as "stop"),
CM SDK events, and expirations of its timer. To simplify thread-safety,
IfsServer allows these stimuli to be enqueued when received, for subsequent
processing by a single thread. To do this, the run
method has
a canonical dispatch loop to dequeue and handle such stimuli by calling the
following methods, implemented by the IfsServer subclass:
handleTimerExpired
:
when the IfsServer timer expires
handleStopRequest
:
when stop
is called to request the server to stop
handleSuspendRequest
:
when suspend
is called to request the server to suspend
handleResumeRequest
:
when resume
is called to request the server to resume
handlePriorityChangeRequest
:
when setPriority
is called to change the server's priority
handlePropertyChangeRequest
:
when setProperty
is called to change a dynamic property
of the server
processEvent
:
to process an event received
Servers should operate against services already running on the node. A server should not start its own service.
A server can write to its node's log by calling log
.
For testing purposes, a server can be run "standalone", not on a node.
To do this, the server should provide a static main
method
that obtains a ParameterTable, starts a service, constructs the server,
calls the six-argument initialize
method, and finally calls
start
to run the server.
Modifier and Type | Class and Description |
---|---|
class |
IfsServer.ServerRequest
A ServerRequest is structure holding a Server request.
|
LEVEL_HIGH, LEVEL_LOW, LEVEL_MEDIUM, LEVEL_OFF
SERVERSTATUS_DISPOSED, SERVERSTATUS_RUNNING, SERVERSTATUS_STARTING, SERVERSTATUS_STOPPED, SERVERSTATUS_STOPPING, SERVERSTATUS_SUSPENDED, SERVERSTATUS_UNKNOWN
Constructor and Description |
---|
IfsServer()
Constructs an IfsServer.
|
Modifier and Type | Method and Description |
---|---|
protected LibrarySession |
checkSession()
Gets the default session for this Server, performing additional
checks to ensure the session is still connected and valid.
|
protected LibrarySession |
connectSession()
Gets a default LibrarySession for this Server.
|
protected LibrarySession |
constructSession()
Constructs a new LibrarySession for this Server.
|
protected Long |
convertTimerInterval(String value)
Computes the number of milliseconds in a period of time specified
as a string.
|
protected Long |
convertTimerInterval(String value,
long defValue)
Computes the number of milliseconds in a period of time specified
as a string, and deault to the specified value if the specified
string does not conform or is null.
|
protected Long |
convertTimerInterval(String value,
String daySuffix,
String hourSuffix,
String minuteSuffix,
String secondSuffix)
Computes the number of milliseconds in a period of time specified
as a string.
|
void |
dispose()
Disposes this Server.
|
protected Date |
getLastTimerActivation()
Gets the time at which the timer last generated a "timer expiration"
request for this Server.
|
IfsLogger |
getLogger()
Gets the appropriate logger for this server.
|
protected Date |
getNextTimerActivation()
Gets the time at which the timer will next generate a "timer expiration"
request for this Server.
|
protected LibraryService |
getService()
Gets the default service for this Server.
|
protected Long |
getTimerActivationPeriod()
Gets the activation period, based on this Server's configuration parameters.
|
protected String |
getTimerClassName()
Gets the fully qualified Timer class name.
|
protected AttributeValueTable |
getTimerConfiguration()
Gets the Timer Configuration.
|
protected void |
handlePriorityChangeRequest()
Called when this Server's priority is changed.
|
protected void |
handlePropertyChangeRequest(AttributeValue av)
Called when a dynamic property of this Server is set or changed.
|
protected void |
handlePropertyChangeRequest(String name,
AttributeValue av)
Called when a dynamic property of this Server is set or changed.
|
protected void |
handleRequest(IfsServer.ServerRequest request)
Handles the specified pending request for this Server.
|
protected void |
handleRequests()
Dispatches any pending requests for this Server.
|
protected void |
handleResumeRequest()
Called when this Server is requested to resume.
|
protected void |
handleServerStateControllerRequest(AttributeValue av)
Handle a "check ServerState: Request.
|
protected void |
handleStopRequest()
Called when this Server is requested to stop.
|
protected void |
handleSuspendRequest()
Called when this Server is requested to suspend.
|
protected void |
handleTimerExpired()
Called when the Server's timer expires.
|
void |
initialize()
Perform one time initialization tasks upon loading.
|
boolean |
isNonCompeting()
Returns indication as to whether this server is non-competing.
|
boolean |
isPropertyReadonly(String name)
Gets whether the specified dynamic property is readonly.
|
protected boolean |
isServiceAvailable()
Ensures that the underlying service has connectivity to the database.
|
protected boolean |
isTimerActive()
Gets whether the timer for this Server is started.
|
protected boolean |
isTokenNonCompeting()
Returns indication as to whether the server token is non-competing.
|
protected void |
postCheckServerStateRequest(Object payload)
Posts a "check ServerState) request to this Server.
|
protected void |
postRequest(int type,
Object payload)
Posts a request to this Server.
|
protected void |
postRun()
The post-run tasks for this Server.
|
protected void |
preRun()
The pre-run tasks for this Server.
|
protected void |
processEvent(IfsEvent event)
Processes an IfsEvent previously placed in this Server's event
queue by
queueEvent . |
protected void |
processEvents()
Dispatches any IfsEvents previously placed in this Server's event
queue by
queueEvent . |
protected void |
queueEvent(IfsEvent event)
Queues an IfsEvent for this Server.
|
protected void |
resetTimer()
Resets the timer for this Server.
|
void |
restart()
Requests this Server to restart.
|
void |
resume()
Requests this Server to resume.
|
protected abstract void |
run()
The run tasks for this Server.
|
protected void |
serviceAvailabilityCheckNeeded()
Sets an indication that the service should be checked to ensure
it is available.
|
void |
setPriority(int priority)
Sets the priority of this Server.
|
void |
setProperty(AttributeValue av)
Sets the value of the specified dynamic property for this Server.
|
void |
setProperty(String name,
AttributeValue av)
Sets the value of the specified dynamic property for this Server.
|
void |
start()
Requests this Server to start.
|
protected void |
startTimer()
Starts a timer that will generate "timer expiration" requests for
this Server at a specified interval.
|
void |
stop()
Requests this Server to stop.
|
protected boolean |
stopRequested()
Indicates this Server should stop.
|
protected void |
stopTimer()
Stops the timer for this Server.
|
void |
suspend()
Requests this Server to suspend.
|
void |
timerExpired()
Notififcation that the timer has expired.
|
protected void |
waitForServiceAvailability()
Ensures that the underlying service has connectivity to the database.
|
protected void |
waitServer()
Blocks the current thread until one of the following occurs.
|
acquireSession, constructLibrarySessionPool, createServerState, deregister, disconnectSession, getConfigurationOverridesTable, getConfigurationTable, getCredential, getDesiredStatus, getIfsHome, getInitialConfigurationTable, getLoggerForLegacyLogging, getName, getNode, getNodeName, getOracleHome, getParameterTable, getPriority, getProperties, getProperty, getServerConfigurationName, getServerState, getServerStateValue, getServerType, getServiceName, getSession, getStateTable, getStatus, getSystemUserCredential, handleServerConfigurationOverrideRequest, handleServerStateEvent, initialize, initialize, isAgent, isDisposed, isInitialized, isLogged, log, log, log, releaseSession, releaseSession, setDesiredStatus, setDesiredStatus, setSessionTimeoutPrevented, setStateProperty, setStatus, startStandalone, startStandalone, supportsPriority, supportsSuspendResume, toStatusLabel, toStatusLabel, toStatusLabel, verifyNotDisposed, verifyNotDisposed
public IfsServer() throws IfsException
Subclasses should provide a zero-argument constructor.
IfsException
- if the operation failspublic void initialize() throws Exception
initialize
in class Server
Exception
- if the operation failspublic void start() throws IfsException
start
in interface ServerInterface
IfsException
- (IFS-45164) if the operation failspublic void stop() throws IfsException
stop
in interface ServerInterface
IfsException
- (IFS-45165) if the operation failspublic void restart() throws IfsException
Restart is equivalent to a stop followed by a start. This method is only called from within a Server when it detects a problem where a restart might help to automatically resolve it.
restart
in interface ServerInterface
IfsException
- (IFS-45166) if the operation failspublic void suspend() throws IfsException
suspend
in interface ServerInterface
IfsException
- (IFS-45167) if the operation failspublic void resume() throws IfsException
resume
in interface ServerInterface
IfsException
- (IFS-45168) if the operation failspublic void dispose() throws IfsException
This deregisters the Server to unload it from the CM SDK node. The Server must already be stopped.
Subclasses that override this method should call
super.dispose()
unless they intend to
veto the dispose request.
dispose
in interface ServerInterface
IfsException
- (IFS-45169) if the operation failspublic void setPriority(int priority) throws IfsException
The priority must be between Thread.MIN_PRIORITY
and Thread.MAX_PRIORITY
, inclusive.
If this Server is starting, running, or suspended, this method
will post a priority change request, which will trigger a call
to handlePriorityChangeRequest
when the canonical
dispatch loop of run
calls handleRequests
.
However, if this Server is stopped, this method will instead
synchronously invoke handlePriorityChangeRequest
in the invoking thread. Finally, if the Server is stopping or
disposed, this method will throw an exception indicating this.
setPriority
in interface ServerInterface
setPriority
in class Server
priority
- the priorityIfsException
- (IFS-45171) if the operation failspublic void setProperty(AttributeValue av) throws IfsException
If this Server is starting, running, or suspended, this method
will post a property change request, which will trigger a call
to handlePropertyChangeRequest
when the canonical
dispatch loop of run
calls handleRequests
.
However, if this Server is stopped, this method will instead
synchronously invoke handlePropertyChangeRequest
in the invoking thread. Finally, if the Server is stopping or
disposed, this method will throw an exception indicating this.
setProperty
in interface ServerInterface
av
- the property; the name of the AttributeValue
must be set and is the property nameIfsException
- (IFS-45174) if the operation failspublic void setProperty(String name, AttributeValue av) throws IfsException
If this Server is starting, running, or suspended, this method
will post a property change request, which will trigger a call
to handlePropertyChangeRequest
when the canonical
dispatch loop of run
calls handleRequests
.
However, if this Server is stopped, this method will instead
synchronously invoke handlePropertyChangeRequest
in the invoking thread. Finally, if the Server is stopping or
disposed, this method will throw an exception indicating this.
name
- the property nameav
- the property valueIfsException
- (IFS-45174) if the operation failspublic boolean isPropertyReadonly(String name) throws IfsException
Readonly properties cannot be set using setProperty
.
isPropertyReadonly
in interface ServerInterface
name
- the property namesetProperty
IfsException
- (IFS-45176) if the operation failspublic IfsLogger getLogger()
Typically overridden by subclasses to return the IfsLogger associatged with the specific server.
protected final LibraryService getService() throws IfsException
Equivalent to LibraryService.findService(getServiceName())
.
IfsException
- (IFS-45373) if the operation failsprotected final LibrarySession connectSession() throws IfsException
IfsException
- if the operation failsprotected final LibrarySession constructSession() throws IfsException
IfsException
- if the operation failsprotected final LibrarySession checkSession() throws IfsException
IfsException
- (IFS-45363) if the operation failsprotected void preRun() throws Exception
This method is invoked each time this Server is started.
Unless overridden, no operation is performed by this method.
The Server status is SERVERSTATUS_STARTING
while this method executes. When this method returns, the
status changes to SERVERSTATUS_RUNNING
and
run
is invoked. However, if this method throws,
the status is set to SERVERSTATUS_STOPPING
and
postRun
is invoked.
Exception
- if the operation failsprotected abstract void run()
Override this method with tasks to be performed by this
Server. This method is called after preRun
each time this Server is started. The server status is
SERVERSTATUS_RUNNING
while this method executes.
When this method terminates (by returning or throwing), the
status is set to SERVERSTATUS_STOPPING
and
postRun
is invoked.
The run
method should provide a loop to dispatch
requests and events. The canonical form of this loop is:
try { while (!stopRequested()) { try { handleRequests(); if (stopRequested()) { break; } processEvents(); waitServer(); } catch (Throwable t) { s_Logger.log(Level.WARNING, "Exception in dispatch loop", t); } } catch (Throwable t) { s_Logger.log(Level.WARNING, "Run failed", t); } }
protected void postRun()
This method is invoked each time this Server is stopped, whether by the
run
method returning or either the preRun
or
run
methods throwing. Unless overridden, no operation is
performed by this method. While this method executes, the server status
is SERVERSTATUS_STOPPING
. When this method terminates (by
either returning or throwing), the status of the server is set to
SERVERSTATUS_STOPPED
.
protected boolean stopRequested()
This method is invoked by the canonical dispatch loop of
the run
method. The default implementation
of handleStopRequest
causes subsequent calls
to this method to return true
.
protected final void startTimer() throws IfsException
The timer behavior is governed by a set of server configuration parameters:
IFS.SERVER.TIMER.ActivationPeriod
:
The frequency of timer events. Must be specified for the timer
to be activated. The value is an integer, followed by an optional
unit ("H" for hours, "M" for minutes, "S" for seconds; if no unit
is specified, milliseconds is used). Examples:
IFS.SERVER.TIMER.InitialTimeOfDay
:
The time of day for the first timer expiration. If omitted, the
time of the first timer expiration is instead determined by the
IFS.SERVER.TIMER.InitialDelay
parameter. The value
is specified as "HH:mm:ss". Examples:
IFS.SERVER.TIMER.InitialDelay
:
The delay before the first timer expiration, relative to when the
Server is started. If both IFS.SERVER.TIMER.InitialDelay
and IFS.SERVER.TIMER.InitialTimeOfDay
are omitted, the
initial delay defaults to IFS.SERVER.TIMER.ActivationPeriod
.
Has the same format as IFS.SERVER.TIMER.ActivationPeriod
.
Examples:
If the timer is already started, it is stopped and restarted.
IfsException
- (IFS-45364) if the operation failsprotected final void stopTimer() throws IfsException
If the timer is not started, this method has no effect.
IfsException
- (IFS-45365) if the operation failsprotected final void resetTimer() throws IfsException
This has the effect of preventing the next "timer expired" event from occurring until the Activation Period elapses relative to the current time. If the timer is not started, this method has no effect.
IfsException
- (IFS-45374) if the operation failsprotected final boolean isTimerActive() throws IfsException
IfsException
- (IFS-45366) if the operation failsprotected final Date getLastTimerActivation() throws IfsException
IfsException
- (IFS-45367) if the operation failsprotected final Date getNextTimerActivation() throws IfsException
IfsException
- (IFS-45368) if the operation failsprotected final void queueEvent(IfsEvent event) throws IfsException
This method is typically called by the handleEvent
method of an IfsEventHandler. The event remains in the Server's
event queue until processEvents
is called by the
Server's run method, at which point processEvent
is called to dispatch the event.
IfsException
- (IFS-45369) if the operation failsprotected final void processEvents() throws IfsException
queueEvent
.
This method is invoked by the canonical dispatch loop of the
run
method. It results in calls to the method
processEvent
. These calls occur in the same thread
that called this method. Should one of these calls throw, event
dispatching will cease, any events not yet dispatched will remain
in this Server's event queue, and this method will rethrow the
exception.
IfsException
- (IFS-45371) if the operation failsprotected void processEvent(IfsEvent event) throws Exception
queueEvent
.
This method is called by processEvents
. Override
it to perform tasks in response to an event. Unless overridden,
no operation is performed by this method.
The processEvents
method will rethrow any exception
thrown by this method.
event
- the eventException
- if the operation failsprotected void postRequest(int type, Object payload)
type
- the enumerated request typepayload
- the request payloadprotected void postCheckServerStateRequest(Object payload)
Called from Node.
payload
- the request payloadprotected final void handleRequests() throws IfsException
This method is invoked by the canonical dispatch loop of
the run
method. It results in calls to
handleRequest
, which in turn calls
handleTimerExpired
,
handleStopRequest
,
handleSuspendRequest
,
handleResumeRequest
,
handlePriorityChangeRequest
,
and handlePropertyChangeRequest
.
These calls occur in the same thread that called this method.
Should one of these methods throw, request handling will cease,
any requests not yet dispatched will remain pending, and this
method will rethrow the exception.
IfsException
- (IFS-45370) if the operation failsprotected void serviceAvailabilityCheckNeeded()
protected void waitForServiceAvailability()
protected boolean isServiceAvailable()
protected void handleRequest(IfsServer.ServerRequest request) throws IfsException
This method can be overridden by subclasses to process requests
custom for the particular agent. The implmentation in this
base class handles the standard requests, which result in calls to
handleRequest
, which in turn calls
handleTimerExpired
,
handleStopRequest
,
handleSuspendRequest
,
handleResumeRequest
,
handlePriorityChangeRequest
,
or handlePropertyChangeRequest
.
These calls occur in the same thread that called this method.
Should one of these methods throw, request handling will cease,
any requests not yet dispatched will remain pending, and this
method will rethrow the exception.
IfsException
- (IFS-45370) if the operation failsprotected final void waitServer() throws IfsException
queueEvent
is called to enqueue an event
This method is invoked by the canonical dispatch loop of the
run
method.
IfsException
- (IFS-45372) if the operation failsprotected void handleTimerExpired() throws Exception
This method is called by handleRequests
. Override
it to perform tasks when the timer expires. Unless overridden,
no operation is performed by this method.
The handleRequests
method will rethrow any exception
thrown by this method.
Exception
- if the operation failsprotected void handleStopRequest() throws Exception
This method is called by handleRequests
. Override it
to perform tasks upon a request to stop. If not overridden, this
method simply causes subsequent calls to stopRequested
to return true
.
The handleRequests
method will rethrow any exception
thrown by this method.
Exception
- if the operation failsprotected void handleSuspendRequest() throws Exception
This method is called by handleRequests
. Override
it to perform tasks upon a suspend request. Unless overridden,
no operation is performed by this method.
If this method returns without throwing, the Server's status is
set to SERVERSTATUS_SUSPENDED
.
The handleRequests
method will rethrow any exception
thrown by this method.
Exception
- if the operation failsprotected void handleResumeRequest() throws Exception
This method is called by handleRequests
. Override
it to perform tasks upon a resume request. Unless overridden,
no operation is performed by this method.
If this method returns without throwing, the Server's status is
set to SERVERSTATUS_RUNNING
.
The handleRequests
method will rethrow any exception
thrown by this method.
Exception
- if the operation failsprotected void handlePriorityChangeRequest() throws Exception
This method is called by handleRequests
. Override
it to perform tasks upon a priority change. To obtain the new
priority, call getPriority
. If not overridden,
this method simply changes the priority of the current thread.
The handleRequests
method will rethrow any exception
thrown by this method.
Exception
- if the operation failsprotected void handlePropertyChangeRequest(String name, AttributeValue av) throws Exception
This method is called by handleRequests
. Override
it to perform tasks when a dynamic property is set or changed.
If not overridden, this method simply causes the requested
property to be changed.
The handleRequests
method will rethrow any exception
thrown by this method.
A Server may also call this method to set the value of a dynamic
property. Unlike calling setProperty
, calling this
method sets the property's value synchronously, and also allows
the value of a readonly property to be set.
name
- the property nameav
- the property valueException
- if the operation failsprotected void handlePropertyChangeRequest(AttributeValue av) throws Exception
This method is called by handleRequests
. Override
it to perform tasks when a dynamic property is set or changed.
If not overridden, this method simply causes the requested
property to be changed.
The handleRequests
method will rethrow any exception
thrown by this method.
A Server may also call this method to set the value of a dynamic
property. Unlike calling setProperty
, calling this
method sets the property's value synchronously, and also allows
the value of a readonly property to be set.
av
- the property (name and value assumed to be set)Exception
- if the operation failsprotected void handleServerStateControllerRequest(AttributeValue av) throws Exception
av
- the ServerState valueException
- if the operation failsprotected AttributeValueTable getTimerConfiguration() throws IfsException
Subclasses may override this to derive different values for the timer settings (see oracle.ifs.core.agents.AccessControlListIndexAgent).
IfsException
- if the operation failsprotected String getTimerClassName() throws IfsException
IfsException
- if the operation failsprotected Long getTimerActivationPeriod() throws IfsException
IfsException
- if the operation failsprotected Long convertTimerInterval(String value) throws IfsException
For example, convert "36s" to new Long(36000).
value
- string value to be convertedIfsException
- (IFS-45348) if the operation failsprotected Long convertTimerInterval(String value, long defValue)
value
- string value to be converteddefValue
- string value to be convertedprotected Long convertTimerInterval(String value, String daySuffix, String hourSuffix, String minuteSuffix, String secondSuffix) throws IfsException
For example, convert "36s" to 36000 ms. The suffixes are specified explicitly.
value
- string value to be converteddaySuffix
- suffix used for dayhourSuffix
- suffix used for hourminuteSuffix
- suffix used for minutesecondSuffix
- suffix used for secondIfsException
- (IFS-45348) if the operation failspublic void timerExpired()
timerExpired
in interface TimerContext
public boolean isNonCompeting() throws IfsException
This assists in determining if this instance is a ClusterServer that competes - meaning that only one instance of it should be running.
IfsException
- if the operation failsprotected boolean isTokenNonCompeting() throws IfsException
A non-competing token is one that always assumes a Primary registration type, and always attempts to free the ApplicationToken upon unregistration.
IfsException
- if the operation failsCopyright © 2023. All rights reserved.