API Changes
There are a large number of backwards incompatible changes between 1.X and the prototype version. This page aims to get your server and code through the changes and back up and running.
To get started quickly, here’s some before and after examples for various actions in the API.
Warning
Although most of the code is valid Java, in some cases it has been shortened for brevity and should be considered pseudo code
Connecting
- Connection is now a single call passing a URL
- There is no need to specify the role any more, this is determined by the system
Prototype Connect | 1.X Connect |
---|
GeneosConnection gConn = new GeneosConnectionJms();
gConn.set("url", "ws://localhost:8001/jms");
gConn.set("username", "user");
gConn.set("password", "password");
gConn.set("roles", "ROLE_USER");
ServiceInitialiserJms.initJmsServices(gConn);
gConn.connect();
| String addr = "geneos.cluster://localhost:2551";
String user = "user";
String pwd = "password";
Connection conn =
OpenAccess.connect(addr+"?username="+user+"&password="+pwd);
|
- Callbacks for status and errors are now passed directly to OpenAccess.connect
Prototype Connect Callback | 1.X Connect Callback |
---|
GeneosConnection gConn = new GeneosConnectionJms();
gConn.set("url", "ws://localhost:8001/jms");
ServiceInitialiserJms.initJmsServices(gConn);
gConn.addListener(new GeneosConnectionListener(){
void onConnectionEvent(GeneosConnectionEvent event) {
switch(event.getType()) {
case CONNECT: /* Connected... */ break;
case CLOSE: /* Connection closed... */ break;
case ERROR: event.getException().printStackTrace(); break;
}
}
});
gConn.connect();
| Connection conn =
OpenAccess.connect("geneos.cluster://localhost:2551",
new Callback<Connection.Status>() {
public void callback(Connection.Status status) {
switch (status) {
case CONNECTED: /* Connected... */ break;
case CLOSED: /* Connection closed... */ break;
}
}
},
new ErrorCallback() {
public void error(Exception exception) {
exception.printStackTrace();
}
}
);
|
Query for data
- All queries are now executed directly on the Connection, no more ServiceRepositoryHolder.getRepository().getXXX for each type of data
- The Callback and data type are determined by the Query type passed to Connection.execute
- The second argument to Connection.execute (null in these examples) is an ErrorCallback. There was no equivalent in the prototype API.
Prototype DataSet Query | 1.X DataSet Query |
---|
ServiceRepositoryHolder.getRepository().getDataSetStreamService().query(
"//pathToSomeItems",
new StreamCallback<DataSetEvent>() {
public void onStreamEvent(final DataSetEvent event) {
// Do stuff
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
conn.execute(DataSetQuery.create("//pathToSomeItems"),
new Callback<DataSetChange>() {
public void callback(final DataSetChange data) {
// Do stuff
}
}, null // null error callback is bad practice!
);
|
Prototype DataView Query | 1.X DataView Query |
---|
ServiceRepositoryHolder.getRepository().getDataViewStreamService().query(
"//pathToDataView",
new StreamCallback<DataViewEvent>() {
public void onStreamEvent(final DataSetEvent event) {
// Do stuff
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
conn.execute(DataViewQuery.create("//pathToDataView"),
new Callback<DataViewChange>() {
public void callback(final DataViewChange data) {
// Do stuff
}
}, null // null error callback is bad practice!
);
|
Commands
- Getting a list of commands is now very similar to querying other data, unlike before where the callback was special
- Unlike the other data queries, the prototype did have an error callback, so the 1.X example includes the equivalent ErrorCallback
- Executing commands previously had separate callbacks for change types, now you can use CommandExecutionChange.getStatus
Prototype CommandList Query | 1.X CommandSet Query |
---|
ServiceRepositoryHolder.getRepository().getCommandProvider().list(
"//uniqueIdPath",
new CommandProvider.ListHandler() {
public void onSuccess(final List<Command> commands) {
// Do stuff
}
public void onFailure(final CommandException error) {
// Handle error
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
conn.execute(CommandSetQuery.create("//uniqueIdPath"),
new Callback<CommandSet>() {
public void callback(final CommandSet data) {
// Do stuff
}
},
new ErrorCallback() {
public void error(final Exception exception) {
// Handle error
}
}
);
|
Prototype Command Execute | 1.X Command Execute |
---|
ServiceRepositoryHolder.getRepository().getCommandProvider().execute(
"//uniqueIdPath", CommandBuilder.create("commandId")
new ExecuteHandlerAdapter(){
public void onCommandOutput(final String someOutput) {
// Process output
}
public void onComplete(final CommandExecution finalResult) {
// Command complete
}
// .. other callbacks omitted
public void onFailure(final CommandException error) {
// Handle error
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
conn.execute(CommandExecuteQuery.create("//uniqueIdPath", "commandId"),
new Callback<CommandExecutionChange>() {
public void callback(final CommandExecutionChange data) {
switch (data.getStatus()) {
case RUNNING: /* Process output */ break;
case COMPLETE: /* Command complete */ break;
// Other cases omitted...
}
}
},
new ErrorCallback() {
public void error(final Exception exception) {
// Handle error
}
}
);
|
Prototype Command Arguments | 1.X Command Arguments |
---|
Command commandToRun = CommandBuilder.create("commandId")
.argument("argument A", "value A")
.argument("argument B", "other value").get();
ServiceRepositoryHolder.getRepository().getCommandProvider().execute(
"//uniqueIdPath", commandToRun, ...
| CommandExecuteQuery query =
CommandExecuteQuery.create("//uniqueIdPath", "commandId");
query.putArgument("argument A", "value A");
query.putArgument("argument B", "other value");
Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
conn.execute(query, ...
|
Tracking state
- The prototype API would pass an Event to each callback that would contain the change and the updated data. The data could not safely be used on other thread, as it would be updated by the system at any time. The only valid approach was to copy the whole structure on every event.
- The 1.X API only passes the changes (delta’s) to the callback. For many use cases this is sufficient, and reduces the memory footprint
- If you wish to maintain the state of the data in the client, we provide ‘Tracker’ classes that can be used as shown below
- You can safely pass the change to another thread and track the state there if required.
Prototype State | 1.X State |
---|
ServiceRepositoryHolder.getRepository().getDataSetStreamService().query(
"//pathToSomeItems",
new StreamCallback<DataSetEvent>() {
public void onStreamEvent(final DataSetEvent event) {
DataSet sourceDataSet = event.getDataSet();
// 'sourceDataSet' is the updated in memory copy.
// It cannot be used on other threads
DataSet copyDataSet = DataSetCopy.dataSetCopy(sourceDataSet);
// The client code now owns 'copyDataSet'.
// You are free to use it on other threads
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
// Declare a tracker outside of the callback to track state
final DataSetTracker tracker = new DataSetTracker();
conn.execute(DataSetQuery.create("//pathToSomeItems"),
new Callback<DataSetChange>() {
public void callback(final DataSetChange data) {
// Apply the change...
DataSet dataSet = tracker.update(data);
// 'dataSet' is now reflects the current state.
// It can be safely used in other threads
}
}, null // null error callback is bad practice!
);
|
Snapshots
- You can emulate the Snapshot behaviour by using the Request object
Prototype Snapshot | 1.X Snapshot |
---|
DataSet dataSet =
SnapshotDataSet.snapshotDataSet("//pathToSomeItems",
5, TimeUnit.SECONDS);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
DataSetQuery query = DataSetQuery.create("//pathToSomeItems");
Request request = new Request(conn);
Response<DataSet> response = request.execute(query, 5, TimeUnit.SECONDS)
System.out.println(response.get());
conn.close();
|
Printing
- toString on all relevant data classes now returns a formatted string, so there is no need for the Printer classes
Prototype Printing | 1.X Printing |
---|
ServiceRepositoryHolder.getRepository().getDataSetStreamService().query(
"//pathToSomeItems",
new StreamCallback<DataSetEvent>() {
public void onStreamEvent(final DataSetEvent event) {
DataSetPrinter.print(event.getDataSet());
}
}
);
| Connection conn = OpenAccess.connect("geneos.cluster://localhost:2551");
final DataSetTracker tracker = new DataSetTracker();
conn.execute(DataSetQuery.create("//pathToSomeItems"),
new Callback<DataSetChange>() {
public void callback(final DataSetChange data) {
DataSet dataSet = tracker.update(data);
System.out.println(dataSet);
}
}, null // null error callback is bad practice!
);
|
Changes to data models
- The
getContent()
in DataSet has been replaced with getItems()
- The DataView also does not contain
getContent()
instead it provides access to its content through getRowHeader()
, getColumnHeaders()
, getHeadlines()
and getRows
methods - Both data structures now contain
getProperties
instead of getMetaData
to access any user facing data
Access to data in prototype | Access to data in 1.X |
---|
DataSet dataSet = /* ... */
//get dataset items
List<DataSetItem> dataSetItems = dataSet.getContent().getItems();
//get metadata
Map<String, String> dataSetMetaData = dataSet.getMetaData();
DataView dataView = /* ... */
//get row header
String rowHeader = dataView.getContent().getRowHeader();
//get column headers
List<DataViewColumnHeader> columnHeaders =
dataView.getContent().getColumnHeaders();
//get dataview headlines
List<DataViewHeadline> headlines = dataView.getContent().getHeadlines();
//get rows in dataview
List<DataViewRow> rows = dataView.getContent().getRows();
//get cells in first row
List<DataViewCell> cells = rows.get(0).getCells();
//get metadata
Map<String, String> dataViewMetaData = dataView.getMetaData();
| DataSet dataSet = /* ... */
//get dataSet items
List<DataSetItem> dataSetItems = dataSet.getItems();
//get properties instead of metadata
Map<String, String> dataSetOProperties = dataSet.getProperties();
DataView dataView = /* ... */
//get row header
String rowHeader = dataView.getRowHeader();
//column headers are now list of strings
List<String> columnHeaders =
dataView.getColumnHeaders();
//get dataview headlines
List<DataViewHeadline> headlines = dataView.getHeadlines();
//get rows in dataview
List<DataViewRow> rows = dataView.getRows();
//get cells in first row
List<DataViewCell> cells = rows.get(0).getCells();
//get properties instead of metadata
Map<String, String> dataViewProperties = dataView.getProperties();
|
Configuration
Configure on the first run
Set host and port in Prototype | Set host and port in 1.X |
---|
//in ~/.geneos/openaccess/config/system.properties
gateway.hostname=<HOSTNAME_OR_IP>gateway.websocket.port=<PORT>
| //in config/application.conf
akka {
remote.netty.tcp
{
hostname = "HOSTNAME_OR_IP" port = <PORT> }
}
|
You can find further details in /cluster/config
Adding a gateway connection
Prototype | 1.X |
---|
<!-- in ~/geneos/openaccess/config/gateways.xml -->
<gatewayConnections>
<gatewayConnection>
<enabled>true</enabled>
<primary>
<host>primary_host</host>
<port>30000</port>
</primary>
<user>username</user>
<password>password</password>
</gatewayConnection>
</gatewayConnections>
| //in config/settings.conf
gateways {
"connection name" {
host = "primary_host" port = 30000
user = "username" password = "password" }
}
|
You can find further details in /cluster/gateway_connections