Architecture
Center Subscription
Overview
Centers can subscribe to each other using Center Replication, but you may wish to send or receive Center information to an external application.
3forge supports this via the Center Client where custom Java code can be used to subscribe real-time via a listener to tables within a Center.
After subscribing, the Java Client will receive ADD, UPD, and DEL messages as the contents of the table changes.
Setup
Requirements
- An active 3forge Center (you will need to know where it is hosted and what ports it uses)
- An instance of the 3forge Java Client Listener interface. A full description of the Center client and its methods can be found on this page
To set up a custom Java client that subscribes to a Center, you will need to include the following files in the Java project's class path:
These will be located in the amione/lib directory of your 3forge installation.
You will also need to include the path to your 3forge license file in the arguments of the JVM: -Df1.license.file=<path_to_license_file>.txt.
Example
This example implements the AmiCenterClientListener Java interface. This listens directly to the Center port of a Center instance.
The step-by-step breakdown is as follows:
- Implement an
AmiCenterClientListener in Java that listens to a Center.
- Subscribe to a specific table in the Center: "SampleTable".
- Define behaviors for connecting to the Center and sending/receiving messages.
Java Code: AmiCenterClientListener.java
The Java code below contains connection details for a locally hosted 3forge Center with default ports (port 3270).
It subscribes to a table SampleTable and logs any messages it receives.
| package centerclient;
import java.io.IOException;
import java.util.Collections;
import com.f1.ami.amicommon.AmiCenterDefinition;
import com.f1.ami.amicommon.centerclient.AmiCenterClientListener;
import com.f1.ami.amicommon.centerclient.AmiCenterClientObjectMessage;
import com.f1.ami.client.AmiCenterClient;
import com.f1.bootstrap.ContainerBootstrap;
public class AmiCenterSubscriptionSample implements AmiCenterClientListener {
public static void main(String[] args) throws NumberFormatException, IOException {
new ContainerBootstrap(AmiCenterSubscriptionSample.class, args);
final AmiCenterClient client = new AmiCenterClient("SampleClient");//Create Client Adapter
client.connect("PrimaryCenter", "localhost", 3270, new AmiCenterSubscriptionSample());//Subscribe to Center running on localhost:3270 and label that Center as "PrimaryCenter"
client.subscribe("PrimaryCenter", Collections.singleton("SampleTable"));//Subscribe to the SampleTable table on the PrimaryCenter
}
@Override
public void onCenterMessage(AmiCenterDefinition center, AmiCenterClientObjectMessage m) {
System.out.println("Message: " + center + " ==> " + m);
}
@Override
public void onCenterDisconnect(AmiCenterDefinition center) {
System.out.println("Disconnect:" + center);
}
@Override
public void onCenterConnect(AmiCenterDefinition center) {
System.out.println("Connect: " + center);
}
@Override
public void onCenterMessageBatchDone(AmiCenterDefinition center) {
//Transaction completed
}
}
|
Using the Listener
-
Start AmiCenterSubscriptionSample and the Center.
-
Run the following commands in the Center's shell tool:
-
| DROP TABLE IF EXISTS SampleTable;
CREATE PUBLIC TABLE SampleTable(Name String,qty int,px double);
INSERT INTO SampleTable VALUES("MSFT",100,15.5),("IBM",200,17.3);
|
-
| DELETE FROM SampleTable WHERE Name=="MSFT"
|
-
| INSERT INTO SampleTable VALUES("GLW",300,18);
|
-
| UPDATE SampleTable set qty=qty+1;
|
- The
AmiCenterSubscriptionSample logs should output something similar to the following:
-
| Connect: Center0-PrimaryCenter[localhost:3270]
Message: Center0-PrimaryCenter[localhost:3270] ==> ADD:2812001594:SampleTable{Name=MSFT, qty=100, px=15.5}
Message: Center0-PrimaryCenter[localhost:3270] ==> ADD:2812001595:SampleTable{Name=IBM, qty=200, px=17.3}
Message: Center0-PrimaryCenter[localhost:3270] ==> DEL:2812001594:SampleTable{}
Message: Center0-PrimaryCenter[localhost:3270] ==> ADD:2812001597:SampleTable{Name=GLW, qty=300, px=18.0}
Message: Center0-PrimaryCenter[localhost:3270] ==> UPD:2812001595:SampleTable{qty=201}
Message: Center0-PrimaryCenter[localhost:3270] ==> UPD:2812001597:SampleTable{qty=301}
|
Note
The unique identifiers will be different (2812001594...).
If commands a,b,c,d are ran in a single operation then the instructions will be conflated into 2 ADDs.