Geneos


The end of life (EOL) date for this module is on 31 January, 2020.

Recommended Reads

Migrating from the prototype to 1.X

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 Connect1.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 Callback1.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 Query1.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 Query1.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 Query1.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 Execute1.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 Arguments1.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 State1.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 Snapshot1.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 Printing1.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 prototypeAccess 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 PrototypeSet 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

Prototype1.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