From d77f394b7d54afc983317d8dc86b90b244325816 Mon Sep 17 00:00:00 2001 From: Marcin Date: Mon, 29 Jun 2020 20:22:55 +0100 Subject: [PATCH 1/2] use item name as description when description not provided --- .../jmx/openmbean/CompositeTypeFactory.java | 22 +++---- .../openmbean/CompositeTypeFactoryTest.java | 62 +++++++++++++++++++ 2 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 quickfixj-core/src/test/java/org/quickfixj/jmx/openmbean/CompositeTypeFactoryTest.java diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/openmbean/CompositeTypeFactory.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/openmbean/CompositeTypeFactory.java index 7146528c55..667c3289de 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/openmbean/CompositeTypeFactory.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/openmbean/CompositeTypeFactory.java @@ -21,31 +21,26 @@ import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import java.util.ArrayList; - -// NOTE: Do not parameterize OpenType for Java6 since it will -// be incompatible with Java 5 +import java.util.List; public class CompositeTypeFactory { + private final String name; private final String description; - private final ArrayList itemNames = new ArrayList<>(); - private final ArrayList itemDescriptions = new ArrayList<>(); - - @SuppressWarnings("rawtypes") // Java 5/6 incompatibility - private final ArrayList itemTypes = new ArrayList<>(); + private final List itemNames = new ArrayList<>(); + private final List itemDescriptions = new ArrayList<>(); + private final List> itemTypes = new ArrayList<>(); public CompositeTypeFactory(String name, String description) { this.name = name; this.description = description; } - @SuppressWarnings("rawtypes") // Java 5/6 incompatibility - public void defineItem(String itemName, OpenType itemType) { - defineItem(itemName, null, itemType); + public void defineItem(String itemName, OpenType itemType) { + defineItem(itemName, itemName, itemType); } - @SuppressWarnings("rawtypes") // Java 5/6 incompatibility - public void defineItem(String itemName, String itemDesc, OpenType itemType) { + public void defineItem(String itemName, String itemDesc, OpenType itemType) { itemNames.add(itemName); itemDescriptions.add(itemDesc); itemTypes.add(itemType); @@ -57,5 +52,4 @@ public CompositeType createCompositeType() throws OpenDataException { .toArray(new String[itemDescriptions.size()]), itemTypes .toArray(new OpenType[itemTypes.size()])); } - } diff --git a/quickfixj-core/src/test/java/org/quickfixj/jmx/openmbean/CompositeTypeFactoryTest.java b/quickfixj-core/src/test/java/org/quickfixj/jmx/openmbean/CompositeTypeFactoryTest.java new file mode 100644 index 0000000000..55a82038ba --- /dev/null +++ b/quickfixj-core/src/test/java/org/quickfixj/jmx/openmbean/CompositeTypeFactoryTest.java @@ -0,0 +1,62 @@ +package org.quickfixj.jmx.openmbean; + +import org.junit.Before; +import org.junit.Test; + +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.SimpleType; + +import static org.junit.Assert.assertEquals; + +public class CompositeTypeFactoryTest { + + private CompositeTypeFactory underTest; + + @Before + public void setUp() { + underTest = new CompositeTypeFactory("user", "registered user"); + } + + @Test + public void shouldCreateCompositeTypeWithDescription() throws OpenDataException { + underTest.defineItem("age", "age of a person", SimpleType.INTEGER); + underTest.defineItem("email", "email address", SimpleType.STRING); + underTest.defineItem("dob", "date of birth", SimpleType.DATE); + + CompositeType compositeType = underTest.createCompositeType(); + assertEquals("user", compositeType.getTypeName()); + assertEquals("registered user", compositeType.getDescription()); + assertEquals("javax.management.openmbean.CompositeData", compositeType.getClassName()); + + assertEquals(SimpleType.INTEGER, compositeType.getType("age")); + assertEquals("age of a person", compositeType.getDescription("age")); + + assertEquals(SimpleType.STRING, compositeType.getType("email")); + assertEquals("email address", compositeType.getDescription("email")); + + assertEquals(SimpleType.DATE, compositeType.getType("dob")); + assertEquals("date of birth", compositeType.getDescription("dob")); + } + + @Test + public void shouldCreateCompositeTypeWithoutDescription() throws OpenDataException { + underTest.defineItem("age", SimpleType.INTEGER); + underTest.defineItem("email", SimpleType.STRING); + underTest.defineItem("dob", SimpleType.DATE); + + CompositeType compositeType = underTest.createCompositeType(); + assertEquals("user", compositeType.getTypeName()); + assertEquals("registered user", compositeType.getDescription()); + assertEquals("javax.management.openmbean.CompositeData", compositeType.getClassName()); + + assertEquals(SimpleType.INTEGER, compositeType.getType("age")); + assertEquals("age", compositeType.getDescription("age")); + + assertEquals(SimpleType.STRING, compositeType.getType("email")); + assertEquals("email", compositeType.getDescription("email")); + + assertEquals(SimpleType.DATE, compositeType.getType("dob")); + assertEquals("dob", compositeType.getDescription("dob")); + } +} From 96cd591c0fd6359a0be348fa5a5cd9968bdeceb4 Mon Sep 17 00:00:00 2001 From: Marcin Date: Tue, 30 Jun 2020 11:20:40 +0100 Subject: [PATCH 2/2] initiator addresses fix --- .../jmx/mbean/connector/ConnectorAdmin.java | 11 +-- .../mbean/connector/SocketAcceptorAdmin.java | 14 ++-- .../connector/SocketAcceptorAdminMBean.java | 2 +- .../mbean/connector/SocketInitiatorAdmin.java | 69 +++++++++++++++++-- .../connector/SocketInitiatorAdminMBean.java | 7 +- .../mina/initiator/IoSessionInitiator.java | 13 ++++ 6 files changed, 89 insertions(+), 27 deletions(-) diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/ConnectorAdmin.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/ConnectorAdmin.java index c4d48fa243..a9ed58971d 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/ConnectorAdmin.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/ConnectorAdmin.java @@ -44,6 +44,9 @@ import java.util.List; abstract class ConnectorAdmin implements ConnectorAdminMBean, MBeanRegistration { + + protected static final TabularDataAdapter TABULAR_DATA_ADAPTER = new TabularDataAdapter(); + private final Logger log = LoggerFactory.getLogger(getClass()); public final static String ACCEPTOR_ROLE = "ACCEPTOR"; @@ -52,9 +55,7 @@ abstract class ConnectorAdmin implements ConnectorAdminMBean, MBeanRegistration private final Connector connector; - private static final TabularDataAdapter tabularDataAdapter = new TabularDataAdapter(); - - private final SessionJmxExporter sessionExporter; + protected final SessionJmxExporter sessionExporter; private final JmxExporter jmxExporter; @@ -120,7 +121,7 @@ public TabularData getSessions() throws IOException { sessions.add(new ConnectorSession(session, sessionExporter.getSessionName(sessionID))); } try { - return tabularDataAdapter.fromBeanList("Sessions", "Session", "sessionID", sessions); + return TABULAR_DATA_ADAPTER.fromBeanList("Sessions", "Session", "sessionID", sessions); } catch (OpenDataException e) { throw JmxSupport.toIOException(e); } @@ -134,7 +135,7 @@ public TabularData getLoggedOnSessions() throws OpenDataException { names.add(sessionExporter.getSessionName(sessionID)); } } - return tabularDataAdapter.fromArray("Sessions", "SessionID", toObjectNameArray(names)); + return TABULAR_DATA_ADAPTER.fromArray("Sessions", "SessionID", toObjectNameArray(names)); } private ObjectName[] toObjectNameArray(List sessions) { diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdmin.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdmin.java index 19a066c6ba..77268bac4f 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdmin.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdmin.java @@ -41,29 +41,22 @@ public class SocketAcceptorAdmin extends ConnectorAdmin implements SocketAccepto private final AbstractSocketAcceptor acceptor; - private static final TabularDataAdapter tabularDataAdapter = new TabularDataAdapter(); - - private final SessionJmxExporter sessionExporter; - public SocketAcceptorAdmin(JmxExporter jmxExporter, AbstractSocketAcceptor connector, ObjectName connectorName, SessionJmxExporter sessionExporter) { super(jmxExporter, connector, connectorName, connector.getSettings(), sessionExporter); - this.sessionExporter = sessionExporter; acceptor = connector; } public static class SessionAcceptorAddressRow { private final SessionID sessionID; - private final SocketAddress acceptorAddress; - private final ObjectName sessionName; - public SessionAcceptorAddressRow(SessionID sessionID, SocketAddress accceptorAddress, + public SessionAcceptorAddressRow(SessionID sessionID, SocketAddress acceptorAddress, ObjectName sessionName) { this.sessionID = sessionID; - this.acceptorAddress = accceptorAddress; + this.acceptorAddress = acceptorAddress; this.sessionName = sessionName; } @@ -82,6 +75,7 @@ public ObjectName getSessionName() { } } + @Override public TabularData getAcceptorAddresses() throws IOException { List rows = new ArrayList<>(); for (Map.Entry entry : acceptor.getAcceptorAddresses().entrySet()) { @@ -90,7 +84,7 @@ public TabularData getAcceptorAddresses() throws IOException { rows.add(new SessionAcceptorAddressRow(sessionID, address, sessionExporter.getSessionName(sessionID))); } try { - return tabularDataAdapter.fromBeanList("AcceptorAddresses", "AddressInfo", "sessionID", + return TABULAR_DATA_ADAPTER.fromBeanList("AcceptorAddresses", "AddressInfo", "sessionID", rows); } catch (OpenDataException e) { throw JmxSupport.toIOException(e); diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdminMBean.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdminMBean.java index 58156cd3fb..04bd53248a 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdminMBean.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketAcceptorAdminMBean.java @@ -22,7 +22,7 @@ import javax.management.openmbean.TabularData; /** - * Management inteface for a socket acceptor connector. + * Management interface for a socket acceptor connector. */ public interface SocketAcceptorAdminMBean extends ConnectorAdminMBean { diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdmin.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdmin.java index 590e6dfa92..5ba134ebc2 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdmin.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdmin.java @@ -20,19 +20,21 @@ import org.quickfixj.jmx.JmxExporter; import org.quickfixj.jmx.mbean.JmxSupport; import org.quickfixj.jmx.mbean.session.SessionJmxExporter; -import org.quickfixj.jmx.openmbean.TabularDataAdapter; +import quickfix.SessionID; import quickfix.mina.initiator.AbstractSocketInitiator; +import quickfix.mina.initiator.IoSessionInitiator; import javax.management.ObjectName; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.TabularData; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.ArrayList; +import java.util.List; class SocketInitiatorAdmin extends ConnectorAdmin implements SocketInitiatorAdminMBean { - private final TabularDataAdapter tabularDataAdapter = new TabularDataAdapter(); - private final AbstractSocketInitiator initiator; protected SocketInitiatorAdmin(JmxExporter jmxExporter, AbstractSocketInitiator connector, @@ -41,10 +43,18 @@ protected SocketInitiatorAdmin(JmxExporter jmxExporter, AbstractSocketInitiator initiator = connector; } - public TabularData getEndpoints() throws IOException { + + @Override + public TabularData getInitiatorAddresses() throws IOException { + List rows = new ArrayList<>(); + for (IoSessionInitiator initiator : initiator.getInitiators()) { + SessionID sessionID = initiator.getSessionID(); + rows.add(new SessionInitiatorAddressRow(sessionID, initiator.getLocalAddress(), + initiator.getSocketAddresses(), + sessionExporter.getSessionName(sessionID))); + } try { - return tabularDataAdapter.fromBeanList("Endpoints", "Endpoint", "sessionID", - new ArrayList<>(initiator.getInitiators())); + return TABULAR_DATA_ADAPTER.fromBeanList("InitiatorAddresses", "AddressInfo", "sessionID", rows); } catch (OpenDataException e) { throw JmxSupport.toIOException(e); } @@ -53,4 +63,51 @@ public TabularData getEndpoints() throws IOException { public int getQueueSize() { return initiator.getQueueSize(); } + + public static class SessionInitiatorAddressRow { + + private final SessionID sessionID; + private final SocketAddress localInitiatorAddress; + private final SocketAddress[] initiatorAddresses; + private final ObjectName sessionName; + + public SessionInitiatorAddressRow(SessionID sessionID, SocketAddress localInitiatorAddress, + SocketAddress[] initiatorAddresses, ObjectName sessionName) { + this.sessionID = sessionID; + this.localInitiatorAddress = localInitiatorAddress; + this.initiatorAddresses = initiatorAddresses; + this.sessionName = sessionName; + } + + public String getLocalInitiatorAddress() { + if (localInitiatorAddress == null) { + return null; + } else { + InetSocketAddress inetSocketAddress = (InetSocketAddress) localInitiatorAddress; + return inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort(); + } + } + + public String getInitiatorAddresses() { + StringBuilder builder = new StringBuilder(128); + + InetSocketAddress inetSocketAddress = (InetSocketAddress) initiatorAddresses[0]; + builder.append(inetSocketAddress.getAddress().getHostAddress()).append(':').append(inetSocketAddress.getPort()); + + for (int i = 1; i < initiatorAddresses.length; i++) { + inetSocketAddress = (InetSocketAddress) initiatorAddresses[i]; + builder.append(',').append(inetSocketAddress.getAddress().getHostAddress()).append(':').append(inetSocketAddress.getPort()); + } + + return builder.toString(); + } + + public SessionID getSessionID() { + return sessionID; + } + + public ObjectName getSessionName() { + return sessionName; + } + } } diff --git a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdminMBean.java b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdminMBean.java index 78f1445353..de31395501 100644 --- a/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdminMBean.java +++ b/quickfixj-core/src/main/java/org/quickfixj/jmx/mbean/connector/SocketInitiatorAdminMBean.java @@ -24,11 +24,8 @@ public interface SocketInitiatorAdminMBean extends ConnectorAdminMBean { /** - * Get initiator communication endpoints - * - * @return a table of endpoint information - * @throws IOException + * @return the initiator addresses configured for this connector's sessions. */ - TabularData getEndpoints() throws IOException; + TabularData getInitiatorAddresses() throws IOException; } diff --git a/quickfixj-core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java b/quickfixj-core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java index 13835402d8..81b0d70e1a 100644 --- a/quickfixj-core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java +++ b/quickfixj-core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java @@ -29,6 +29,7 @@ import quickfix.ConfigError; import quickfix.LogUtil; import quickfix.Session; +import quickfix.SessionID; import quickfix.SystemTime; import quickfix.mina.CompositeIoFilterChainBuilder; import quickfix.mina.EventHandlingStrategy; @@ -373,4 +374,16 @@ synchronized void stop() { } SessionConnector.closeManagedSessionsAndDispose(reconnectTask.ioConnector, true, log); } + + public SessionID getSessionID() { + return reconnectTask.fixSession.getSessionID(); + } + + public SocketAddress getLocalAddress() { + return reconnectTask.localAddress; + } + + public SocketAddress[] getSocketAddresses() { + return Arrays.copyOf(reconnectTask.socketAddresses, reconnectTask.socketAddresses.length); + } }