Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

The code below is a simple example of how to use the Messaging Client. The JmsMessagingClient constructor includes three required parameters and two optional parameters. The required parameters include the client ID, the MessagingListener instance, and the connection properties mentioned above. The optional parameters include a message selector and flag which determines whether durable subscribers should be used to listen over the topics listed in the properties. More information about each of the available parameters can be found in the JmsMessagingClient javadocs.

Code Block
javajava
borderStylesolid
java
public class Example implements MessagingListener {
    MessagingClient messagingClient;
    public void start() throws MessagingException {
        Properties properties = new Properties();
        properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
                               "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
        properties.setProperty(Context.PROVIDER_URL, "tcp://localhost:61616");
        properties.setProperty(JMSManager.CONNECTION_FACTORY_NAME, "ConnectionFactory");
        properties.setProperty("topic.fedora", "fedora.apim.*");
        messagingClient = new JmsMessagingClient("example1", this, properties, false);
        messagingClient.start();
    }
    public void stop() throws MessagingException {
        messagingClient.stop(false);
    }
    public void onMessage(String clientId, Message message) {
        String messageText = "";
        try {
            messageText = ((TextMessage)message).getText();
        } catch(JMSException e) {
            System.err.println("Error retrieving message text " + e.getMessage());
        }
        System.out.println("Message received: " + messageText + " from client " + clientId);
    }
}

...

The content of messages sent by Fedora takes the form of feed entries based on the Atom Syndication Format. These messages correspond to API-M method calls, indicating the name of the method, its parameters, return value, and other information about the method. Each message will be similar to the following example:

xml
Code Block
xml
borderStylesolid
xml
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:fedora-types="http://www.fedora.info/definitions/1/0/types/"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <id>urn:uuid:3773e144-1b63-4dde-8786-464243af9186</id>
  <updated>2008-04-14T22:35:13.953Z</updated>
  <author>
    <name>fedoraAdmin</name>
    <uri>http://localhost:8080/fedora</uri>
  </author>
  <title type="text">purgeObject</title>
  <category term="demo:5" scheme="fedora-types:pid" label="xsd:string"></category>
  <category term="purge message" scheme="fedora-types:logMessage" label="xsd:string"></category>
  <category term="false" scheme="fedora-types:force" label="xsd:boolean"></category>
  <summary type="text">demo:5</summary>
  <content type="text">2008-04-14T22:35:13.953Z</content>
</entry>

...

  • <id> uniquely identifies each entry
  • <updated> indicates the date and time at which the call occurred
  • <author> identifies the initiation point of the API-M method call
    • <name> specifies the name of the user making the call
    • <uri> corresponds to the baseURL of the Fedora repository from which the call originated
  • <title> specifies the method name
  • Each <category> corresponds to a method's argument:
    • Wiki MarkupThe term indicates the argument value. However, null values are indicated as "null", and non-null xsd:base64Binary values are indicated as "\[OMITTED\]".
    • The scheme indicates the argument name
    • The label indicates the argument datatype
  • <summary> corresponds to the PID of the object operated on by the method, if applicable.
  • <content> corresponds to the textual representation of the method's return value, noting the following:
    • Null values are represented as "null".
    • fedora-types:ArrayOfString values are represented as a comma-separated list, e.g. "value1, value2, value3".
    • Wiki MarkupNon-null xsd:base64Binary values are not returned, and only indicated as "\[OMITTED\]". Wiki Markup
    • Non-null fedora-types:Datastream values are not returned, and only indicated as "\[OMITTED\]".
    • fedora-types:RelationshipTuple values are represented in Notation3 (N3).

...

  1. upon startup, load the ActiveMQ embedded broker that ships with Fedora;
  2. configure the embedded broker to:
    1. forward Fedora messages to a remote broker, if the remote broker is available;
    2. if the remote broker is not available, store the messages until the remote broker becomes available, at which point it will forward the stored messages to it
  3. use the ActiveMQ "failover" “failover” transport to attempt periodic reconnections to the remote broker when it is unavailable

...

  1. You will need to make a few jars available to Fedora so it can load and process the ActiveMQ configuration file. Drop the jars xbean-spring-3.4.3.jar and spring-context-2.5.6.jar files into the Fedora webapp WEB-INF/lib directory. Most spring applications provide these jars; if you are using Apache Servicemix as the container for your remote broker, they can be found in the SERVICEMIX_HOME/lib directory.
  2. Create the Fedora activemq.xml file, put it in FEDORA_HOME/server/config. xml
    Code Block
    xml
    borderStylesolid
    xml
    <beans xmlns:amq="http://activemq.apache.org/schema/core">
    
      <!-- ActiveMQ JMS Broker configuration -->
      <amq:broker id="broker" useShutdownHook="false">
    
        <amq:managementContext>
          <amq:managementContext connectorPort="1093" createConnector="false"/>
        </amq:managementContext>
    
        <!-- Your remote broker, configured with failover -->
        <amq:networkConnectors>
          <amq:networkConnector name="fedorabridge" dynamicOnly="true" uri="static:(failover:(tcp://0.0.0.0:61617))"/>
        </amq:networkConnectors>
    
        <!-- The directory where Fedora will store the ActiveMQ data -->
        <amq:persistenceAdapter>
          <amq:amqPersistenceAdapter directory="file:./data/amq"/>
        </amq:persistenceAdapter>
      </amq:broker>
    
      <!-- Set this to prevent objects from being serialized when
           passed along to your embedded broker;  saves some overhead processing -->
      <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
         <property name="objectMessageSerializationDefered" value="false"/>
    
      </bean>
    
    </beans>
    
    
    This piece of the config file creates the bridge to the remote broker, configured in failover mode. The dynamicOnly property ensures that messages are forwarded only when there is a consumer available to receive them.
    Code Block
    xmlxml
    borderStylesolid
    xml
    <amq:networkConnectors>
      <amq:networkConnector name="fedorabridge" dynamicOnly="true" uri="static:(failover:(tcp://0.0.0.0:61617))"/>
    </amq:networkConnectors>
    
  3. Configure Fedora to read the activemq.xml file upon startup, create the embedded broker.
    Make sure messaging is enabled in fedora.fcfg: xml
    Code Block
    xml
    borderStylesolid
    xml
    <module role="org.fcrepo.server.messaging.Messaging" class="org.fcrepo.server.messaging.MessagingModule">
      <comment>Fedora's Java Messaging Service (JMS) Module</comment>
      <param name="enabled" value="true"/>
    [...]
    
    Also change the java.naming.provider.url parameter:
    Code Block
    xmlxml
    borderStylesolid
    xml
    <param name="java.naming.provider.url" value="vm://localhost?brokerConfig=xbean:file:/path/to/fedora_home/server/config/activemq.xml"/>
    
  4. Restart Fedora, and start up your remote broker (or the other way around: it no longer matters).
    The ActiveMQ failover transport documentation contains a list of useful parameters that you can use to configure connection management to the remote broker (max reconnect attempts, period between reconnects, etc.)

...