source: trunk/README.Plugins.txt

Last change on this file was 1, checked in by root, 13 years ago

Initial import

File size: 8.6 KB
1CSP Plugins
4As of 0.8.6 the proxy has a plugin framework. This is another one-hour hack so don't read too much into it.
6NOTE: With 0.8.10 it is also possible to add connector implementations using these same methods, although connectors
7wouldn't be loaded under the plugins section (see README.ConaxConnector.txt).
9Some ideas for plugins:
10- CA emulation, have the proxy read/fetch/use the static keys and the clients wont have to.
11- Your own simplified CS protocol.
12- BISS.
13- Log aggregation, have the proxy receive udp/syslog events from servers and clients to aid troubleshooting.
14- Fault management, triggering nagios or zabbix alarms on critical errors.
16To create a new plugin, first read README.Compiling.txt and ensure you can successfully build the proxy itself.
17The source code itself is the ultimate documentation and to find a place to start, you can use the following param when
18starting java: -Dcom.bowman.cardserv.util.tracexmlcfg=true
19That will keep track of where all proxy.xml accesses are made from in the code, and dump it to file when
20you request it via the admin section of the status web.
22Then use the following procedure:
23 1. Copy one of the existing plugin directory trees and rename it (e.g MyTestPlugin).
24 2. Edit build.xml in the plugin dir and search/replace the old name to match yours.
25 3. Place any extra dependencies your plugin will need in the lib dir. Remove any jars that are not needed.
26 NOTE: As of 0.9.0, the plugin class loader can fetch needed jars for you, to avoid having to distribute them with
27 the plugin. See below for details.
28 4. Start editing the source, renaming the main plugin class and file to match your new name.
29 5. Run ant in the plugin dir to compile and build the jar (it ends up in dist).
31Place the jar in proxy-home/plugins, then add the config elements for the plugin to proxy.xml, e.g:
33 ...
34 <plugin class="com.bowman.cardserv.MyTestPlugin" enabled="true" jar-file="mytestplugin.jar">
35 <plugin-config>
36 // plugin specific config here
37 </plugin-config>
38 </plugin>
39 ...
42The plugin lifecycle is as follows:
43 1. The main plugin class (that implements ProxyPlugin) is instantiated.
44 2. configUpdated() is called with the settings specified for this plugin in proxy.xml.
45 3. Assuming configUpdated() didn't throw any exceptions, start() is called, with a reference to the proxy istself.
46 4. Next time proxy.xml is touched or changed, stop() will be called allowing the plugin to cleanup before unload.
48For most plugins it should be possible to replace the jar file and update/touch proxy.xml to have the new version loaded
49without restarting.
50NOTE: As of 0.8.11, plugin jars are watched for changes, and automatically reloaded when replaced.
52The plugin api is fairly primitive, here's a quick guide for a single class example:
54package com.bowman.cardserv;
55// You can use any package, but there could be some protected methods only accessible from this one in the main classes.
57import com.bowman.cardserv.interfaces.*;
58import com.bowman.cardserv.util.*;
59import com.bowman.cardserv.rmi.*;
60import com.bowman.cardserv.web.*;
61// Depending on what you intend to do, different parts of the proxy source needs to be imported.
64import java.util.*;
67public class MyTestPlugin implements ProxyPlugin {
68// The main class of the plugin must implement this interface: com.bowman.cardserv.interfaces.ProxyPlugin
69// If you want the plugin to have a say in connector selection, also implement: com.bowman.cardserv.interfaces.CwsSelector
70// If you want the plugin to filter replies from connectors (dcw's) implement: com.bowman.cardserv.interfaces.ReplyFilter
72// If your plugin makes use of 3rd party libraries, create an array with the direct urls to each dependency:
73 public static final String[] dependencyUrls = new String[] {
74 "",
75 ""
76 }
78// Methods outlined below...
80 public void configUpdated(ProxyXmlConfig xml) throws ConfigException {
81 // Whenever proxy.xml is changed the plugin will be discarded and reloaded. Settings from proxy.xml available here.
82 // The plugin should verify that they make sense and throw a ConfigException if they dont.
84 // If you have 3rd party dependencies, configure the plugin classloader to fetch them first:
85 PluginClassLoader pcl = (PluginClassLoader)getClass().getClassLoader();
86 pcl.resolveDependencies(dependencyUrls, logger);
87 // Now you can make use of any class from the listed jars.
88 }
90 public void start(CardServProxy proxy) {
91 // Called after configUpdated(). Tells the plugin to initialize everything and start any background jobs etc.
92 // If it needs access to the proxy it should store the reference passed to this method.
93 // This reference can be used to get access to most of the functionality, see MessagingPlugin for one example.
94 // Any control or status commands should be registered here.
95 }
97 public void stop() {
98 // Called before unload is attempted (every time proxy.xml changes, or when the plugin jar is replaced).
99 // The plugin should stop all threads and remove any references to itself that it might have registered elsewhere.
100 // Any control or status commands should be unregistered here.
101 }
103 public String getName() {
104 return "MyTestPlugin"; // Displayname for the plugin
105 }
107 public String getDescription() {
108 return "A test plugin."; // Description
109 }
111 public Properties getProperties() { // arbitrary parameters shown in the proxy-plugins status command output (admin only, 0.9.0+)
112 Properties p = new Properties();
113 p.setProperty("relevant-param", "value");
114 return p;
115 }
117 public CamdNetMessage doFilter(ProxySession proxySession, CamdNetMessage msg) {
118 // Called with every single message sent to the proxy from a client session, or from the proxy back to the sessions.
119 // The plugin can modify the message, return something else entirely, or block it (by doing msg.setFilteredBy("Reason text")).
120 // See the LoggingPlugin or EmmAnalyzerPlugin for examples.
122 return msg; // = do nothing
123 }
125 public byte[] getResource(String path, boolean admin) {
126 // This allows the plugin to export content to the httpd
127 // The following code ensure that anything placed in /web in the plugin jar file is available via the proxy web.
128 // Files are accessed using
129 // The admin flag indicates if the user logged into the web as an admin user.
131 if(path.startsWith("/")) path = path.substring(1);
132 try {
133 DataInputStream dis = new DataInputStream(getClass().getResourceAsStream("/web/" + path));
134 byte[] buf = new byte[dis.available()];
135 dis.readFully(buf);
136 return buf;
137 } catch (IOException e) {
138 return null;
139 }
141 // Note that user login will be required to access anything this way, with one exception:
142 // The plugin will be queried for a file called "load.js" whenever anyone accesses the default status web (cs-status).
143 // This file allows the plugin to hook itself into the javascript in cs-status.war. See GeoipPlugin for an example.
144 }
146 public byte[] getResource(String path, byte[] inData, boolean admin) {
147 // Same as the above method, except for http POST instead of GET.
148 // Can be used to allow file uploads from the web to a plugin (or any custom data from the client side scripting).
150 return null;
151 }
154 // If your plugin implements the CwsSelector interface, the proxy will call this method for every incoming ecm request.
155 // The call includes the session where the message originated, and the connectors (set of name Strings) that the proxy
156 // thinks are valid choices to handle this request. Your plugin can remove names from this list based on the contents
157 // of the CamdNetMessage data, or based on the properties of the user associated with the session.
158 /*
159 public Set doSelection(ProxySession session, CamdNetMessage msg, Set connectors) {
160 return connectors;
161 }
162 */
164 // If your plugin implements the ReplyFilter interface, this method will get called for every connector reply (dcw).
165 // This happens before the proxy does anything with the reply, and allows the plugin to look for and remove bad dcw's.
166 // To change a suspicious dcw reply into a cannot decode, do msg.setCustomData(new byte[0]).
167 // To silently block a reply entirely (probably a bad idea) return null instead of the msg.
168 /*
169 public CamdNetMessage doReplyFilter(CwsConnector connector, CamdNetMessage msg) {
170 return msg; // = do nothing
171 }
172 */
Note: See TracBrowser for help on using the repository browser.