package org.marketcetera.module;
import org.marketcetera.util.misc.ClassVersion;
import javax.management.MXBean;
import java.util.List;
/* $License$ */
/**
* Enables remoting of {@link ModuleManager module manager}.
* All the operations accept primitive java types and strings as parameters,
* so that they can be invoked from simple JMX clients like jconsole.
*
* The following
* APIs accept parameters in special syntax so that they can be translated
* to complex data types that the underlying module manager API accepts.
*
* <h3>Create Module Instance</h3>
* This parameter syntax applies to the second parameter to the API
* {@link #createModule(String, String)}.
* <p>
* The parameter list can have a comma separated list of individual parameters.
* The framework will convert the supplied parameters from string to the
* parameter type specified by the factory via its
* {@link ModuleFactory#getParameterTypes()} method. The conversion from
* string to the appropriate type is supported for following types.
* <ol>
* <li>Java Primitive Types</li>
* <li>Strings</li>
* <li>BigDecimal</li>
* <li>BigInteger</li>
* <li>File</li>
* <li>URL</li>
* <li>ModuleURN</li>
* </ol>
* If the factory accepts a parameter of type that is not included in
* the list above, its instances cannot be created via the JMX API.
* Do note that no mechanism is available to escape a comma character such
* that its not treated as a delimiter between two parameters. ie. none
* of the parameters can include a comma in their value.
* <p>
* Here are some examples of strings that can be used to supply parameter values
* when invoking the create module instance API.
*
* <ul>
* <li>Example 1:</li>
* <ul>
* <li>Parameter Types:ModuleURN, URL, String, BigDecimal</li>
* <li>Parameter Value:
* <code>"metc:surface:color:red,http://red.com,username,12.43"</code>
* </li>
* </ul>
* <li>Example 2:</li>
* <ul>
* <li>Parameter Types:File, boolean, double, BigInteger</li>
* <li>Parameter Value:<code>"c:\\mydir,true,345.643,83723849"</code></li>
* </ul>
* </ul>
*
* <h3>Create Data Flows</h3>
* This parameter syntax applies to the first parameter of APIs
* {@link #createDataFlow(String)} &
* {@link #createDataFlow(String, boolean)}.
* <p>
* The API accepts a series of data requests. Each data request consists of
* a {@link ModuleURN} and an optional string parameter.
* Individual data requests are delimited by a '^' character.
* If a data request needs to include the '^', character it can be escaped
* by including it twice, like so '^^', so that its not interpreted
* as a delimiter between data requests.
* <p>
* Within each data request, the module URN and the parameter are
* separated by ';' character. The first entry is always
* interpreted as the <code>ModuleURN</code>. The second entry is interpreted
* as a string request parameter. The string parameter value can contain
* ';' character and it will not interfere with data request parsing as
* it only looks for the first ';' character in the string and interprets the
* rest of the string as the string parameter value.
* <p>
* Here are some examples of strings that can be used when setting up data
* flows.
* <ul>
* <li>Example 1.</li>
* <ul>
* <li><code>"metc:mdata;symbol=ibm^metc:strategy::vegas^metc:sink"</code></li>
* <li>Sets up a data flow between any market data module that generates
* market data for symbol 'ibm', pipes that data to a strategy named
* 'vegas' and pipes its output to the sink module.</li>
* </ul>
* <li>Example 2.</li>
* <ul>
* <li><code>"metc:mdata:opentick;symbol=java^metc:strategy::charity^metc:server"</code></li>
* <li>Sets up a data flow between opentick market data module, that
* generates market data for symbol 'java', pipes that data to a
* strategy called 'charity' and pipes the trades generated by it to
* the system client module that sends it to the server.</li>
* </ul>
* <li>Example 3.</li>
* <ul>
* <li><code>"metc:mdata;symbol=aapl,goog^metc:cep:esper;select * from Bid^metc:strategy::buy;12^^32^^43"</code></li>
* <li>Sets up a data flow between any market data module that generates
* data for symbols, aapl & goog, pipes that data into the esper module, that
* runs the cep query 'select * from Bid' and pipes its output to
* a strategy module 'buy' that accepts a string parameter '12^32^43'.
* </li>
* </ul>
* </ul>
*
*
*
* @author anshul@marketcetera.com
* @version $Id: ModuleManagerMXBean.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.0.0
*/
@ClassVersion("$Id: ModuleManagerMXBean.java 16154 2012-07-14 16:34:05Z colin $") //$NON-NLS-1$
@MXBean(true)
@DisplayName("Module Framework Operations")
public interface ModuleManagerMXBean {
/**
* Returns a list of URNs of available module providers.
*
* @return the list of URNs of available module providers.
*
* @see ModuleManager#getProviders()
*/
@DisplayName("Fetches the URNs of all the module providers available in the system")
List<String> getProviders();
/**
* Returns a list of URNs of all module instances.
*
* @return a list of URNs of all module instances.
*
* @see ModuleManager#getModuleInstances(ModuleURN)
*/
@DisplayName("Fetches the URNs of all the module instances available in the system")
List<String> getInstances();
/**
* Returns detailed information on a provider, given its URN.
*
* @param providerURN the provider URN
*
* @return the provider details.
*
* @throws RuntimeException if a provider with the supplied
* URN does not exist. OR if the supplied provider URN is not a
* valid URN.
*
* @see ModuleManager#getProviderInfo(ModuleURN)
*/
@DisplayName("Fetches Provider Details")
ProviderInfo getProviderInfo(
@DisplayName("Provider URN")
String providerURN) throws RuntimeException;
/**
* Returns the module instances of the module provider, given its URN.
*
* @param providerURN the providerURN whose module
* instances are requested. If null, all module instances
* are returned.
*
* @return the list or URNs for all the modules
*
* @throws RuntimeException if a provider with the supplied
* URN does not exist. OR if the supplied provider URN is not a
* valid URN.
*
* @see ModuleManager#getModuleInstances(ModuleURN)
*/
@DisplayName("Fetches the URNs of all the module instances registered with the Framework")
List<String> getModuleInstances(
@DisplayName("Provider URN, to return its instances only, null otherwise")
String providerURN)
throws RuntimeException;
/**
* Creates a module instance. An attempt to create a module instance
* for a provider that only supports singleton instances will fail.
* All singleton instances are created when ModuleManager is
* initialized.
* <p>
* This method can only instantiate modules whose creation requires
* only those parameter types as supported by
* {@link org.marketcetera.module.StringToTypeConverter}. If an
* attempt is made to create a module supplying string value for
* an unsupported type, the module creation will fail with a type
* mismatch error.
* <p>
* Parameters of any type can be used to instantiate modules via
* {@link ModuleManager#createModule(ModuleURN, Object[])}.
* However, this API is only available for local invocation as
* JMX doesn't support remoting of any random data type.
*
*
* @param providerURN The provider URN. The value supplied should match
* the value returned by a module factory's
* {@link org.marketcetera.module.ModuleFactory#getProviderURN()} that
* is available in the system.
* @param parameterList the comma separated list of parameters that
* are needed to instantiate the module. The string parameters are
* converted to object types based on type values returned by
* {@link ModuleFactory#getParameterTypes()}. If any of the types
* returned by {@link ModuleFactory#getParameterTypes()} are not
* supported by {@link org.marketcetera.module.StringToTypeConverter},
* this method will fail.
*
* @return the instantiated module's URN
*
* @throws RuntimeException if there were errors creating
* the module
*
* @see #getProviderInfo(String)
*
* @see ModuleManager#createModule(ModuleURN, Object[])
*/
@DisplayName("Creates a new module instance")
String createModule(
@DisplayName("Provider URN")
String providerURN,
@DisplayName("The comma separated list of parameters to create new instance")
String parameterList)
throws RuntimeException;
/**
* Deletes the module identified by the supplied module URN.
* Singleton instances of a module cannot be deleted. The module
* should not be running when this method is invoked, otherwise
* the operation fails with an exception.
*
* @param inModuleURN the module URN, that uniquely identifies
* the module being deleted.
*
* @throws RuntimeException if a module with the supplied
* URN cannot be deleted OR if the supplied module URN is not
* a valid URN. OR if the module matching the URN was not found.
*
* @see ModuleManager#deleteModule(ModuleURN)
*/
@DisplayName("Delete a module instance")
void deleteModule(
@DisplayName("The module instance URN")
String inModuleURN)
throws RuntimeException;
/**
* Returns detailed information on the module having the supplied
* module URN.
*
* @param inModuleURN the module URN
*
* @return the detailed module information.
*
* @throws RuntimeException if a module with the supplied
* URN was not found OR if the supplied URN was invalid. OR if there
* were errors creating module's ObjectName
*
* @see ModuleManager#getModuleInfo(ModuleURN)
*/
@DisplayName("Fetches the module instance details")
ModuleInfo getModuleInfo(
@DisplayName("The module instance URN")
String inModuleURN)
throws RuntimeException;
/**
* Starts the module instance
*
* @param inModuleURN the module instance URN uniquely identifying
* the module that needs to be started.
*
* @throws RuntimeException if there were errors starting the module.
*
* @see ModuleManager#start(ModuleURN)
*/
@DisplayName("Starts a module instance")
void start(
@DisplayName("The module instance URN")
String inModuleURN) throws RuntimeException;
/**
* Stops a module instance. Do note that stopping a module stops
* all the data flows that this module initiated and is participating
* in.
*
* @param inModuleURN the module instance URN uniquely identifying
* the module that needs to be stopped.
*
* @throws RuntimeException if a module with the supplied
* URN was not found OR if the supplied module URN is invalid.
*
* @see ModuleManager#stop(ModuleURN)
*/
@DisplayName("Stops a module instance")
void stop(
@DisplayName("The module instance URN")
String inModuleURN) throws RuntimeException;
/**
* Creates a requested connection between the modules identified by
* the supplied requests. Each data request should uniquely identify
* a module via its URN attribute. Its an error if none or
* multiple modules match the URN.
*
* For each matched module, a request is initiated supplying it the
* data request.
*
* The system will automatically append the sink module to the
* data flow if the last module identified by the request is
* capable of emitting data and if the sink has not been already
* specified as the last module in the pipeline.
*
* Invoking this method is the same as invoking
* <code>createDataFlow(requests,true);</code>
*
* @param inRequests the request instances
*
* @return the ID identifying the data flow.
*
* @throws RuntimeException if any of the requested modules could
* not be found, or instantiated or configured. Or if any of the
* modules were not capable of emitting or receiving data as
* requested. Or if any of the modules didn't understand the
* request parameters or were unable to emit data as requested.
*
* @see ModuleManager#createDataFlow(DataRequest[])
*/
@DisplayName("Creates a new data flow, automatically appending the sink module")
DataFlowID createDataFlow(
@DisplayName("The series of requests specifying the flow")
String inRequests) throws RuntimeException;
/**
* Creates a requested connection between the modules identified by
* the supplied requests. Each data request should uniquely identify
* a module via its URN attribute. Its an error if none or
* multiple modules match the URN.
*
* For each matched module, a request is initiated supplying it the
* data request.
*
* Each of the modules specified in the request should already be
* started for the request to succeed. This request will fail
* if any of the modules specified in the request are not started
* and are not
* {@link Module#isAutoStart() auto-start}.
*
* @param inRequests the request instances
* @param inAppendSink if the sink module should be automatically
* appended to the tail end of the data flow.
*
* @return the ID identifying the data flow.
*
* @throws RuntimeException if any of the requested modules could
* not be found, or instantiated or configured. Or if any of the
* modules were not capable of emitting or receiving data as
* requested. Or if any of the modules didn't understand the
* request parameters or were unable to emit data as requested.
*
* @see ModuleManager#createDataFlow(DataRequest[], boolean)
*
*/
@DisplayName("Creates a data flow")
DataFlowID createDataFlow(
@DisplayName("The series of requests specifying the data flow")
String inRequests,
@DisplayName("If the sink module should be automatically appended to the flow")
boolean inAppendSink)
throws RuntimeException;
/**
* Cancels the data flow identified by the supplied data flow ID.
* Do note that data flows that have been initiated by
* {@link #createDataFlow(String, boolean)} can be canceled by this
* method.
*
* Specifically, data flows created by modules via
* {@link DataFlowSupport#createDataFlow(DataRequest[])}
* cannot be canceled by this method. They can only be canceled by the
* module that initiated the data flow request.
*
* @param inFlowID the data flow ID.
*
* @throws RuntimeException if the data flow, specified by
* the ID, could not be found.
*
* @see ModuleManager#cancel(DataFlowID)
*/
@DisplayName("Cancels an active data flow")
void cancel(
@DisplayName("The data flow ID")
String inFlowID)
throws RuntimeException;
/**
* Returns all the data flows.
*
* @param inIncludeModuleCreated if the data flows created by
* the module should be included in the returned list.
*
* @return the list of IDs of all data flows in the system.
*
* @see ModuleManager#getDataFlows(boolean)
*/
@DisplayName("Gets the list of IDs of all active data flows")
List<DataFlowID> getDataFlows(
@DisplayName("If data flows created by the modules should be included")
boolean inIncludeModuleCreated);
/**
* Returns details of data flow given the data flow ID.
*
* @param inFlowID the data flow ID
*
* @return the data flow details
*
* @throws RuntimeException if the data flow, specified by
* the ID, could not be found.
*
* @see ModuleManager#getDataFlowInfo(DataFlowID)
*/
@DisplayName("Fetches an active data flow's details")
DataFlowInfo getDataFlowInfo(
@DisplayName("The data flow ID")
String inFlowID)
throws RuntimeException;
/**
* Refreshes the set of module providers. Any new module provider
* jars that have been made available in the class path will be
* discovered and processed as a result.
*
* The existing module providers will remain unchanged.
*
* @throws RuntimeException if there were errors initializing
* newly discovered factories.
*
* @see ModuleManager#refresh()
*/
@DisplayName("Refreshes the providers list. Checks to see if any new provider implementations were added")
void refresh() throws RuntimeException;
/**
* Returns the historical record of data flows that are not active
* any more. The maximum size of the returned array is determined
* by the current value of {@link #getMaxFlowHistory()}
*
* @return historical record of data flows that are not active
* any more.
*
* @see ModuleManager#getDataFlowHistory()
*/
@DisplayName("Data flows that are not active any more")
List<DataFlowInfo> getDataFlowHistory();
/**
* The maximum number of data flow records to maintain
* in the data flow history.
*
* @return the maximum number of historical data flow
* records.
*
* @see ModuleManager#getMaxFlowHistory()
*/
@DisplayName("Maximum number of data flow records to retain in data flow history")
int getMaxFlowHistory();
/**
* Sets the maximum number of data flow records to maintain
* in the data flow history.
*
* If the value is reset to a value lower than the current value,
* the older history records are pruned to bring down the size
* of the historical records to the new value.
*
* @param inMaxFlowHistory the maximum number of data flow
* records.
*
* @see ModuleManager#setMaxFlowHistory(int)
*/
@DisplayName("Maximum number of data flow records to retain in data flow history")
void setMaxFlowHistory(
@DisplayName("Maximum number of data flow records to retain in data flow history")
int inMaxFlowHistory);
}