Difference between revisions of "Protege 5 Development Environment"
(→Install From Svn and Server Startup) |
|||
(111 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | = | + | = Introduction = |
− | == Install From Svn | + | The Protege 5 client server allows multiple Protege 5 clients (such as the desktop application) to browse and edit concurrently an ontology stored on a Protege 5 server. |
+ | |||
+ | The Protege 5 client server works in a way similar to SVN (update, commit, resolve conflicts). The conflict resolution mechanism is pluggable. You can read more about the client-server implementation (as a generic OWL-API server) in [http://bmir.stanford.edu/publications/view.php/managing_change_an_ontology_version_control_system this paper]. Here is the first of several videos that I am going to make to demonstrate server features: | ||
+ | <ul> | ||
+ | <li>[http://www.youtube.com/watch?v=x9L2CUQiRBo Protege OWL Client-Server Basics]</li> | ||
+ | </ul> | ||
+ | I have also created a new page [[Protege Server design]] to explain how the Protege Server works for the Protege developers. | ||
+ | |||
+ | = Status = | ||
+ | |||
+ | We are working on an alpha release. Most of the things that would block an alpha release are relatively easy to do. Here are some things that need doing: | ||
+ | <ul> | ||
+ | <li> Figure out how to setup the Protege server as windows service. The startup scripts are now working on linux and on os x.</li> | ||
+ | <li> Develop a security policy for server access. We have a policy mechanism but it is not quite ready yet.</li> | ||
+ | <li> Don't expose passwords as plaintext. We can live with this for a bit and eventually use the fix in Protege 3.</li> | ||
+ | <li> Branching. This shouldn't be too difficult and we plan to permit branches to go across server boundaries (e.g. git-like).</li> | ||
+ | <li> Update backwards to a previous revision. The underlying server implementation now supports this but it has not yet been exposed. </li> | ||
+ | </ul> | ||
+ | Many things already work including | ||
+ | <ul> | ||
+ | <li> Basic Client-Server interaction</li> | ||
+ | <li> Conflict management</li> | ||
+ | <li> Authentication (password is sent as plaintext)</li> | ||
+ | <li> Firewall compatibility</li> | ||
+ | <li> Extended sessions where a user logs out with uncommitted changes and commits them in a later session</li> | ||
+ | </ul> | ||
+ | |||
+ | = Setting Up the Protege 5 Server Development Environment = | ||
+ | |||
+ | == Prerequisites == | ||
+ | |||
+ | * Java 6 or above. We test this with Oracles java more but openjdk should work. | ||
+ | * Maven 2. | ||
+ | * ant is nice as is some useful development environment such as Eclipse or IntelliJ. | ||
+ | |||
+ | == Install and Run From Svn == | ||
First checkout the development tree | First checkout the development tree | ||
<pre> | <pre> | ||
− | svn checkout | + | svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk org.protege.owl.server |
+ | cd org.protege.owl.server | ||
+ | </pre> | ||
+ | To build the server and run the unit and integration tests type: | ||
+ | <pre> | ||
+ | mvn verify | ||
+ | </pre> | ||
+ | If you want to do this without running the tests type: | ||
+ | <pre> | ||
+ | mvn verify -DskipTests | ||
</pre> | </pre> | ||
+ | Note ''mvn package'' will build the main artifact ''target/org.protege.owl.server-*.jar''. In addition, ''mvn verify'' will build a working server in the | ||
+ | ''target/server/server-distribution'' directory. This working server is needed for the integration tests but is made even if the tests are not run. | ||
− | + | In addition to the maven lifecycle, this project has an ant build file to add some scripts that are not naturally part of the maven build lifecycle. The ant targets are | |
− | + | * ''usage'' which will give a complete listing of the ant targets with some additional documentation. | |
− | + | * ''run'' which will run the server, assuming that ''mvn verify'' has already been run. This server will listen for client requests on port 5100. | |
− | + | * ''debug'' which will run the server as above but will allow debugging by waiting for a debugger to connect on port 8100. I believe that most reasonable ide's will have a facility for debugging in this manner and the eclipse capability can be configured with the menu ''Debug→Debug Configurations→Remote Java Application''. | |
− | + | * ''install'' which will install the Protege server library into the copy of a Protege distribution pointed to by the PROTEGE_HOME environment variable. This target assumes that maven has been previously run with a lifecycle goal of ''package'' or better (e.g., ''verify'' works). In order for this to be useful, you will also need to install the protege client. The client installation is described below. Information about the PROTEGE_HOME environment variable and the Protege build scripts can be found [[ConfiguringAntBuildFiles|here]]. | |
− | + | The server that is started in this way is preconfigured with the following usernames and passwords: | |
− | < | + | {| class="wikitable" |
− | </ | + | | fergerson || ncbo |
+ | |- | ||
+ | | redmond || bicycle | ||
+ | |- | ||
+ | | vendetti || protege | ||
+ | |- | ||
+ | | guest || guest | ||
+ | |} | ||
+ | |||
+ | |||
+ | After installing a copy of the server library into PROTEGE_HOME, you may want to install the Protege client so that you can use Protege to connect to the server. To do this first checkout the client code: | ||
+ | <pre> | ||
+ | svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/plugins/org.protege.editor.owl.client/trunk org.protege.editor.owl.client | ||
+ | </pre> | ||
+ | Then you can compile and install it as follows: | ||
+ | <pre> | ||
+ | cd org.protege.editor.owl.client | ||
+ | ant install | ||
+ | </pre> | ||
== Setting up Eclipse == | == Setting up Eclipse == | ||
− | To set up eclipse, unzip the ide-eclipse.zip file. | + | To configure the org.protege.owl.server project follow the following steps: |
+ | # first check the project out from svn (e.g., ''svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk org.protege.owl.server''). This can be done using the eclipse tools but don't worry about how the project gets configured. Then, after making sure that the META-INF/MANIFEST.MF file has not been modified when eclipse checked out the org.protege.owl.server. | ||
+ | # make the maven call ''mvn eclipse:clean eclipse:eclipse''. | ||
+ | # in eclipse either refresh the org.protege.owl.server project, if it is already visible there, or import the project using the ''File→Import→Existing Projects Into Workspace'' menu. | ||
+ | |||
+ | |||
+ | '''''This has changed and will be updated shortly.''''' | ||
+ | |||
+ | |||
+ | To set up eclipse, | ||
+ | <ol> | ||
+ | <li> run "ant install". This step ensures that the built sources will be included in the | ||
+ | org.protege.owl.server project.</li> | ||
+ | <li> unzip the ide-eclipse.zip file.</li> | ||
+ | <li> start eclipse using protege.server as the workspace.</li> | ||
+ | <li>import the projects (File -> Import -> General -> Existing Projects Into Workspace).</li> | ||
+ | </ol> | ||
+ | <b>The next part doesn't work yet but should be coming soon.</b> | ||
+ | This eclipse workspace will come with a couple of runnables: | ||
<ul> | <ul> | ||
− | <li><b>Client</b> starts the Protege OWL Client. | + | <li><b>Client</b> starts the Protege OWL Client.</li> |
− | <li><b>Server</b> | + | <li><b>Server</b> starts the Protege OWL Sever</li> |
− | <li><b>ConnectToAntServer</b> connects to the "ant debug.server" script for debugging. | + | <li><b>ConnectToAntServer</b> connects to the "ant debug.server" script for debugging.</li> |
</ul> | </ul> | ||
+ | |||
+ | == Programatic access to the server == | ||
+ | |||
+ | Some of the key classes used to access the OWL server are: | ||
+ | * the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/Client.java Client] which provides a low level api for server access. A Client object can also be used by classes such as the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/util/ClientUtilities.java ClientUtilities] to provide easy higher level operations such as uploading, downloading and updating ontologies. | ||
+ | * the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/VersionedOntologyDocument.java VersionedOntologyDocument] is an object representing an open ontology corresponding to a server document at a particular document revision. An instantiation of the Client and VersionedOntologyDocument are sufficient to do many operations on a checked out ontology including update, commit and save. | ||
+ | |||
+ | === Connecting to the server programatically === | ||
+ | |||
+ | Connecting to the Protege server involves two steps, authentication and connection. Both the authentication protocol and the connection protocol are fully pluggable on the server, so the exact method of connecting to the server depends on how the server is configured. However currently we only support one authentication mechanism, a very simple username/password mechanism, and two connection protocols, the rmi protocol for accessing the server remotely and the local protocol for accessing a server running on the same jvm. | ||
+ | |||
+ | ==== Accessing the server through rmi ==== | ||
+ | |||
+ | Accessing the server with standard authentication and rmi can be done with the following steps: | ||
+ | <pre> | ||
+ | String host = "171.65.32.14"; | ||
+ | int rmiPort = 4875; | ||
+ | AuthToken tim = RMILoginUtility.login(host, rmiPort, "redmond", "troglodyte"); | ||
+ | RMIClient client = new RMIClient(tim, host, rmiPort); | ||
+ | </pre> | ||
+ | The first step authenticates the user "redmond" on to a server running on the same machine but in a different process. This authentication step results in a AuthToken object (tim) that can then be used to connect to the server. The result of the above steps is an object that implements the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/Client.java Client] interface. | ||
+ | |||
+ | ==== Accessing the server from the same jvm ==== | ||
+ | |||
+ | The best way to access the server when running on the same jvm is to use a local transport. This transport bypasses all network protocols such as rmi and makes a direct connection to the server through java function calls. The manner in which the local transport object is obtained depends on how the server is started. The normal case will be the standard Protege server installation where the code accessing the server is run from a plugin. In this case the LocalTransport object can be obtained from [http://wiki.osgi.org/wiki/Declarative_Services OSGi declarative services]. An example of this approach can be found [https://smi-protege.stanford.edu/repos/protege/protege4/misc/examples/org.protege.owl.server.example/trunk here]. This example can be run by | ||
+ | * checking out the project from the svn [https://smi-protege.stanford.edu/repos/protege/protege4/misc/examples/org.protege.owl.server.example/trunk location]. | ||
+ | * copying the local.properties.template to local.properties and changing the server.home to the appropriate location of the Protege server. | ||
+ | * running ant install to install the plugin to the Protege server plugin directory. | ||
+ | * (re)starting the Protege server so that it will pick up the new plugin. | ||
+ | |||
+ | To obtain the LocalTransport object through declarative services, create a server component declaration like this [https://smi-protege.stanford.edu/repos/protege/protege4/misc/examples/org.protege.owl.server.example/trunk/OSGI-INF/example-component.xml one]: | ||
+ | <pre> | ||
+ | <?xml version="1.0"?> | ||
+ | <scr:component name="org.protege.owl.server.example.component" | ||
+ | immediate="true" | ||
+ | xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"> | ||
+ | <implementation class="org.protege.owl.server.example.EntryImpl"/> | ||
+ | <service> | ||
+ | <provide interface="org.protege.owl.server.example.Entry"/> | ||
+ | </service> | ||
+ | <reference name="LOCALTRANSPORT" | ||
+ | interface="org.protege.owl.server.connect.local.LocalTransport" | ||
+ | bind="initialise" | ||
+ | cardinality="1..1"/> | ||
+ | </scr:component> | ||
+ | </pre> | ||
+ | This declaration tells OSGi declarative services that if it sees a new LocalTransport service then it should instantiate an EntryImpl class and send the new LocalTransport to the EntryImpl's initialise method. | ||
+ | |||
+ | Once the LocalTransport object has been obtained, the client can easily be obtained after authenticating as follows: | ||
+ | <pre> | ||
+ | AuthToken token = Authenticator.localLogin(transport, "redmond", "troglodyte"); | ||
+ | Client client = transport.getClient(token); | ||
+ | </pre> | ||
+ | This client can be used just as any ordinary client. In the example plugin it is used to list the contents of the root directory of the server: | ||
+ | <pre> | ||
+ | RemoteServerDirectory serverRoot = (RemoteServerDirectory) client.getServerDocument(localRoot); | ||
+ | boolean isEmpty = true; | ||
+ | for (RemoteServerDocument doc : client.list(serverRoot)) { | ||
+ | logger.info("Found doc : " + doc); | ||
+ | isEmpty = false; | ||
+ | } | ||
+ | if (isEmpty) { | ||
+ | logger.info("Server root is empty"); | ||
+ | } | ||
+ | </pre> | ||
+ | In a more realistic plugin, [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server.bioportal/trunk the bioportal import plugin] for instance, it is used to copy and update ontologies from the [http://bioportal.bioontology.org/ NCBO BioPortal] into a directory on the Protege server. | ||
+ | |||
+ | |||
+ | Alternatively, if you start the server without OSGi (see [[#Starting the server manually|manual setup]]) then you can arrange to register the LocalTransport somehow so that classes that need it can find it. | ||
+ | |||
+ | === Navigating the server file system === | ||
+ | |||
+ | Documents on the Protege server are identified by an IRI. Thus for example, the root directory for the server at 171.65.32.14:4875 would look like this: | ||
+ | <pre> | ||
+ | rmi-owl2-server://localhost:5100 | ||
+ | </pre> | ||
+ | This IRI can be construced programatically as follows: | ||
+ | <pre> | ||
+ | String host = "171.65.32.14"; | ||
+ | int rmiPort = 4875; | ||
+ | IRI serverIRI = IRI.create(RMIClient.SCHEME + "://" + host + ":" + rmiPort); | ||
+ | </pre> | ||
+ | If you know the name for a server document (the root directory, for example, should always exist) then you can retrieve it directly: | ||
+ | <pre> | ||
+ | client.getServerDocument(serverIRI); | ||
+ | </pre> | ||
+ | This server document ([https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/RemoteOntologyDocument.java RemoteOntologyDocument]) can either be a directory ([https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/RemoteServerDirectory.java RemoteServerDirectory]) or an ontology document | ||
+ | [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/RemoteOntologyDocument.java RemoteOntologyDocument]). | ||
+ | |||
+ | In particular, in the case of the server root directory, the server document is guaranteed to be a directory so it can be directly cast to that type. So if serverIRI represents the server root as described above then we can use the following code: | ||
+ | <pre> | ||
+ | RemoteServerDirectory dir = (RemoteServerDirectory) client.getServerDocument(serverIRI); | ||
+ | </pre> | ||
+ | The contents of a directory can then be listed: | ||
+ | <pre> | ||
+ | for (RemoteServerDocument doc : client.list(dir)) { | ||
+ | System.out.println("found: " + doc.getServerLocation()); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | === Uploading an ontology document to the server === | ||
+ | |||
+ | The pre-requisites for uploading an ontology to a Protege server are a valid client to the server and an open (e.g. instantiation of the OWL api OWLOntology interface) ontology. The [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/util/ClientUtilities.java ClientUtilities] class provides a convenience method for uploading an ontology to the server and a typical invocation looks something like this: | ||
+ | <pre> | ||
+ | VersionedOntologyDocument versionedOntology = ClientUtilities.createServerOntology(client, pizzaLocation, new ChangeMetaData("A tasty pizza"), ontology); | ||
+ | </pre> | ||
+ | where | ||
+ | * client is the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/api/Client.java Client] | ||
+ | * pizzaLocation is an IRI for the ontology document on the server, | ||
+ | * ChangeMetaData is a class containing a commit timestamp and a commit comment. | ||
+ | * ontology is the ontology that you wish to save. | ||
+ | |||
+ | === Downloading an ontology document from the server === | ||
+ | |||
+ | Again the [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/main/java/org/protege/owl/server/util/ClientUtilities.java ClientUtilities] class is the key. The ClientUtilities class has a loadOntology method that takes three arguments: a Client, an ontology manager and a RemoteOntologyDocument to be downloaded. The following code demonstrates how this works: | ||
+ | <pre> | ||
+ | RemoteOntologyDocument doc = (RemoteOntologyDocument) client.getServerDocument(IRI.create(RMIClient.SCHEME + "://" + host + ":" + rmiPort | ||
+ | + "/Pizza.history")); | ||
+ | VersionedOntologyDocument vont = ClientUtilities.loadOntology(client, OWLManager.createOWLOntologyManager(), doc); | ||
+ | OWLOntology ontology = vont.getOntology(); | ||
+ | System.out.println("Axiom count = " + ontology.getAxiomCount()); | ||
+ | </pre> | ||
+ | The caller knows that there is a server-side ontology document representing the pizza ontology and requests a RemoteOntologyDocument pointing to that location. | ||
+ | |||
+ | === Saving a server ontology locally along with server metadata === | ||
+ | |||
+ | === Loading a server ontology and server meta data from a local file === | ||
+ | |||
+ | === Uploading an ontology onto the server === | ||
+ | |||
+ | == Extending the server with a plugin == | ||
+ | |||
+ | Here I will talk about the metaproject and server components. | ||
+ | |||
+ | == Starting the server manually == | ||
+ | |||
+ | In its standard installation, the Protege server is automatically configured based on a configuration file using a [http://en.wikipedia.org/wiki/Dependency_injection dependency injection strategy]. However it is possible to start the server programmatically and this approach to starting and running the server is demonstrated in a [https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk/src/test/java/org/protege/owl/server/DirectServerSetupTest.java unit test]. The key code in this test is the code that starts the server: | ||
+ | <pre> | ||
+ | Server core = new ServerImpl(TestUtilities.ROOT_DIRECTORY, TestUtilities.CONFIGURATION_DIRECTORY); | ||
+ | server = new Authenticator(new ConflictManager(core)); | ||
+ | |||
+ | List<ServerTransport> transports = new ArrayList<ServerTransport>(); | ||
+ | ServerTransport rmiTransport = new RMITransport(rmiPort, rmiPort); | ||
+ | rmiTransport.start(server); | ||
+ | transports.add(rmiTransport); | ||
+ | localTransport = new LocalTransportImpl(); | ||
+ | localTransport.start(server); | ||
+ | transports.add(localTransport); | ||
+ | |||
+ | server.setTransports(transports); | ||
+ | </pre> | ||
+ | The first two lines: | ||
+ | <pre> | ||
+ | Server core = new ServerImpl(TestUtilities.ROOT_DIRECTORY, TestUtilities.CONFIGURATION_DIRECTORY); | ||
+ | server = new Authenticator(new ConflictManager(core)); | ||
+ | </pre> | ||
+ | initialize a new server and configure two filters for the server which provide a simple authentication mechanism and basic conflict management. |
Latest revision as of 14:30, April 25, 2017
Contents
- 1 Introduction
- 2 Status
- 3 Setting Up the Protege 5 Server Development Environment
- 3.1 Prerequisites
- 3.2 Install and Run From Svn
- 3.3 Setting up Eclipse
- 3.4 Programatic access to the server
- 3.4.1 Connecting to the server programatically
- 3.4.2 Navigating the server file system
- 3.4.3 Uploading an ontology document to the server
- 3.4.4 Downloading an ontology document from the server
- 3.4.5 Saving a server ontology locally along with server metadata
- 3.4.6 Loading a server ontology and server meta data from a local file
- 3.4.7 Uploading an ontology onto the server
- 3.5 Extending the server with a plugin
- 3.6 Starting the server manually
Introduction
The Protege 5 client server allows multiple Protege 5 clients (such as the desktop application) to browse and edit concurrently an ontology stored on a Protege 5 server.
The Protege 5 client server works in a way similar to SVN (update, commit, resolve conflicts). The conflict resolution mechanism is pluggable. You can read more about the client-server implementation (as a generic OWL-API server) in this paper. Here is the first of several videos that I am going to make to demonstrate server features:
I have also created a new page Protege Server design to explain how the Protege Server works for the Protege developers.
Status
We are working on an alpha release. Most of the things that would block an alpha release are relatively easy to do. Here are some things that need doing:
- Figure out how to setup the Protege server as windows service. The startup scripts are now working on linux and on os x.
- Develop a security policy for server access. We have a policy mechanism but it is not quite ready yet.
- Don't expose passwords as plaintext. We can live with this for a bit and eventually use the fix in Protege 3.
- Branching. This shouldn't be too difficult and we plan to permit branches to go across server boundaries (e.g. git-like).
- Update backwards to a previous revision. The underlying server implementation now supports this but it has not yet been exposed.
Many things already work including
- Basic Client-Server interaction
- Conflict management
- Authentication (password is sent as plaintext)
- Firewall compatibility
- Extended sessions where a user logs out with uncommitted changes and commits them in a later session
Setting Up the Protege 5 Server Development Environment
Prerequisites
- Java 6 or above. We test this with Oracles java more but openjdk should work.
- Maven 2.
- ant is nice as is some useful development environment such as Eclipse or IntelliJ.
Install and Run From Svn
First checkout the development tree
svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk org.protege.owl.server cd org.protege.owl.server
To build the server and run the unit and integration tests type:
mvn verify
If you want to do this without running the tests type:
mvn verify -DskipTests
Note mvn package will build the main artifact target/org.protege.owl.server-*.jar. In addition, mvn verify will build a working server in the target/server/server-distribution directory. This working server is needed for the integration tests but is made even if the tests are not run.
In addition to the maven lifecycle, this project has an ant build file to add some scripts that are not naturally part of the maven build lifecycle. The ant targets are
- usage which will give a complete listing of the ant targets with some additional documentation.
- run which will run the server, assuming that mvn verify has already been run. This server will listen for client requests on port 5100.
- debug which will run the server as above but will allow debugging by waiting for a debugger to connect on port 8100. I believe that most reasonable ide's will have a facility for debugging in this manner and the eclipse capability can be configured with the menu Debug→Debug Configurations→Remote Java Application.
- install which will install the Protege server library into the copy of a Protege distribution pointed to by the PROTEGE_HOME environment variable. This target assumes that maven has been previously run with a lifecycle goal of package or better (e.g., verify works). In order for this to be useful, you will also need to install the protege client. The client installation is described below. Information about the PROTEGE_HOME environment variable and the Protege build scripts can be found here.
The server that is started in this way is preconfigured with the following usernames and passwords:
fergerson | ncbo |
redmond | bicycle |
vendetti | protege |
guest | guest |
After installing a copy of the server library into PROTEGE_HOME, you may want to install the Protege client so that you can use Protege to connect to the server. To do this first checkout the client code:
svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/plugins/org.protege.editor.owl.client/trunk org.protege.editor.owl.client
Then you can compile and install it as follows:
cd org.protege.editor.owl.client ant install
Setting up Eclipse
To configure the org.protege.owl.server project follow the following steps:
- first check the project out from svn (e.g., svn checkout https://smi-protege.stanford.edu/repos/protege/protege4/libraries/org.protege.owl.server/trunk org.protege.owl.server). This can be done using the eclipse tools but don't worry about how the project gets configured. Then, after making sure that the META-INF/MANIFEST.MF file has not been modified when eclipse checked out the org.protege.owl.server.
- make the maven call mvn eclipse:clean eclipse:eclipse.
- in eclipse either refresh the org.protege.owl.server project, if it is already visible there, or import the project using the File→Import→Existing Projects Into Workspace menu.
This has changed and will be updated shortly.
To set up eclipse,
- run "ant install". This step ensures that the built sources will be included in the org.protege.owl.server project.
- unzip the ide-eclipse.zip file.
- start eclipse using protege.server as the workspace.
- import the projects (File -> Import -> General -> Existing Projects Into Workspace).
The next part doesn't work yet but should be coming soon. This eclipse workspace will come with a couple of runnables:
- Client starts the Protege OWL Client.
- Server starts the Protege OWL Sever
- ConnectToAntServer connects to the "ant debug.server" script for debugging.
Programatic access to the server
Some of the key classes used to access the OWL server are:
- the Client which provides a low level api for server access. A Client object can also be used by classes such as the ClientUtilities to provide easy higher level operations such as uploading, downloading and updating ontologies.
- the VersionedOntologyDocument is an object representing an open ontology corresponding to a server document at a particular document revision. An instantiation of the Client and VersionedOntologyDocument are sufficient to do many operations on a checked out ontology including update, commit and save.
Connecting to the server programatically
Connecting to the Protege server involves two steps, authentication and connection. Both the authentication protocol and the connection protocol are fully pluggable on the server, so the exact method of connecting to the server depends on how the server is configured. However currently we only support one authentication mechanism, a very simple username/password mechanism, and two connection protocols, the rmi protocol for accessing the server remotely and the local protocol for accessing a server running on the same jvm.
Accessing the server through rmi
Accessing the server with standard authentication and rmi can be done with the following steps:
String host = "171.65.32.14"; int rmiPort = 4875; AuthToken tim = RMILoginUtility.login(host, rmiPort, "redmond", "troglodyte"); RMIClient client = new RMIClient(tim, host, rmiPort);
The first step authenticates the user "redmond" on to a server running on the same machine but in a different process. This authentication step results in a AuthToken object (tim) that can then be used to connect to the server. The result of the above steps is an object that implements the Client interface.
Accessing the server from the same jvm
The best way to access the server when running on the same jvm is to use a local transport. This transport bypasses all network protocols such as rmi and makes a direct connection to the server through java function calls. The manner in which the local transport object is obtained depends on how the server is started. The normal case will be the standard Protege server installation where the code accessing the server is run from a plugin. In this case the LocalTransport object can be obtained from OSGi declarative services. An example of this approach can be found here. This example can be run by
- checking out the project from the svn location.
- copying the local.properties.template to local.properties and changing the server.home to the appropriate location of the Protege server.
- running ant install to install the plugin to the Protege server plugin directory.
- (re)starting the Protege server so that it will pick up the new plugin.
To obtain the LocalTransport object through declarative services, create a server component declaration like this one:
<?xml version="1.0"?> <scr:component name="org.protege.owl.server.example.component" immediate="true" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"> <implementation class="org.protege.owl.server.example.EntryImpl"/> <service> <provide interface="org.protege.owl.server.example.Entry"/> </service> <reference name="LOCALTRANSPORT" interface="org.protege.owl.server.connect.local.LocalTransport" bind="initialise" cardinality="1..1"/> </scr:component>
This declaration tells OSGi declarative services that if it sees a new LocalTransport service then it should instantiate an EntryImpl class and send the new LocalTransport to the EntryImpl's initialise method.
Once the LocalTransport object has been obtained, the client can easily be obtained after authenticating as follows:
AuthToken token = Authenticator.localLogin(transport, "redmond", "troglodyte"); Client client = transport.getClient(token);
This client can be used just as any ordinary client. In the example plugin it is used to list the contents of the root directory of the server:
RemoteServerDirectory serverRoot = (RemoteServerDirectory) client.getServerDocument(localRoot); boolean isEmpty = true; for (RemoteServerDocument doc : client.list(serverRoot)) { logger.info("Found doc : " + doc); isEmpty = false; } if (isEmpty) { logger.info("Server root is empty"); }
In a more realistic plugin, the bioportal import plugin for instance, it is used to copy and update ontologies from the NCBO BioPortal into a directory on the Protege server.
Alternatively, if you start the server without OSGi (see manual setup) then you can arrange to register the LocalTransport somehow so that classes that need it can find it.
Documents on the Protege server are identified by an IRI. Thus for example, the root directory for the server at 171.65.32.14:4875 would look like this:
rmi-owl2-server://localhost:5100
This IRI can be construced programatically as follows:
String host = "171.65.32.14"; int rmiPort = 4875; IRI serverIRI = IRI.create(RMIClient.SCHEME + "://" + host + ":" + rmiPort);
If you know the name for a server document (the root directory, for example, should always exist) then you can retrieve it directly:
client.getServerDocument(serverIRI);
This server document (RemoteOntologyDocument) can either be a directory (RemoteServerDirectory) or an ontology document RemoteOntologyDocument).
In particular, in the case of the server root directory, the server document is guaranteed to be a directory so it can be directly cast to that type. So if serverIRI represents the server root as described above then we can use the following code:
RemoteServerDirectory dir = (RemoteServerDirectory) client.getServerDocument(serverIRI);
The contents of a directory can then be listed:
for (RemoteServerDocument doc : client.list(dir)) { System.out.println("found: " + doc.getServerLocation()); }
Uploading an ontology document to the server
The pre-requisites for uploading an ontology to a Protege server are a valid client to the server and an open (e.g. instantiation of the OWL api OWLOntology interface) ontology. The ClientUtilities class provides a convenience method for uploading an ontology to the server and a typical invocation looks something like this:
VersionedOntologyDocument versionedOntology = ClientUtilities.createServerOntology(client, pizzaLocation, new ChangeMetaData("A tasty pizza"), ontology);
where
- client is the Client
- pizzaLocation is an IRI for the ontology document on the server,
- ChangeMetaData is a class containing a commit timestamp and a commit comment.
- ontology is the ontology that you wish to save.
Downloading an ontology document from the server
Again the ClientUtilities class is the key. The ClientUtilities class has a loadOntology method that takes three arguments: a Client, an ontology manager and a RemoteOntologyDocument to be downloaded. The following code demonstrates how this works:
RemoteOntologyDocument doc = (RemoteOntologyDocument) client.getServerDocument(IRI.create(RMIClient.SCHEME + "://" + host + ":" + rmiPort + "/Pizza.history")); VersionedOntologyDocument vont = ClientUtilities.loadOntology(client, OWLManager.createOWLOntologyManager(), doc); OWLOntology ontology = vont.getOntology(); System.out.println("Axiom count = " + ontology.getAxiomCount());
The caller knows that there is a server-side ontology document representing the pizza ontology and requests a RemoteOntologyDocument pointing to that location.
Saving a server ontology locally along with server metadata
Loading a server ontology and server meta data from a local file
Uploading an ontology onto the server
Extending the server with a plugin
Here I will talk about the metaproject and server components.
Starting the server manually
In its standard installation, the Protege server is automatically configured based on a configuration file using a dependency injection strategy. However it is possible to start the server programmatically and this approach to starting and running the server is demonstrated in a unit test. The key code in this test is the code that starts the server:
Server core = new ServerImpl(TestUtilities.ROOT_DIRECTORY, TestUtilities.CONFIGURATION_DIRECTORY); server = new Authenticator(new ConflictManager(core)); List<ServerTransport> transports = new ArrayList<ServerTransport>(); ServerTransport rmiTransport = new RMITransport(rmiPort, rmiPort); rmiTransport.start(server); transports.add(rmiTransport); localTransport = new LocalTransportImpl(); localTransport.start(server); transports.add(localTransport); server.setTransports(transports);
The first two lines:
Server core = new ServerImpl(TestUtilities.ROOT_DIRECTORY, TestUtilities.CONFIGURATION_DIRECTORY); server = new Authenticator(new ConflictManager(core));
initialize a new server and configure two filters for the server which provide a simple authentication mechanism and basic conflict management.