-
-
Save hitxiang/6715b1d25c26eebecd981668520f3bd1 to your computer and use it in GitHub Desktop.
FIX message to JSON convertor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.collect.ImmutableSet; | |
import com.google.common.reflect.ClassPath; | |
import com.google.gson.Gson; | |
import com.google.gson.JsonObject; | |
import quickfix.FieldNotFound; | |
import quickfix.Message; | |
import java.io.IOException; | |
import java.lang.reflect.Field; | |
import java.util.HashMap; | |
import java.util.Iterator; | |
import java.util.Map; | |
public class FIX2Json { | |
private static final Gson gson = new Gson(); | |
private Map<Integer, String> tagToNameMap; | |
public FIX2Json() { | |
tagToNameMap = new HashMap<>(); | |
tagToNameMap.putAll(getTagToNameMap("quickfix.field")); | |
} | |
private static Map<Integer, String> getTagToNameMap(String packageName) { | |
Map<Integer, String> tagToNameMap = new HashMap<>(); | |
try { | |
ClassPath classPath = ClassPath.from(ClassLoader.getSystemClassLoader()); | |
ImmutableSet<ClassPath.ClassInfo> classes = classPath.getTopLevelClasses(packageName); | |
for (ClassPath.ClassInfo classInfo : classes) { | |
Field field; | |
try { | |
field = classInfo.load().getField("FIELD"); | |
} catch (NoSuchFieldException e) { | |
continue; | |
} | |
int fieldTag = field.getInt(null); | |
String fieldName = classInfo.getSimpleName(); | |
tagToNameMap.put(fieldTag, fieldName); | |
} | |
} catch (IOException | IllegalAccessException e) { | |
e.printStackTrace(); | |
} | |
return tagToNameMap; | |
} | |
public String fix2Json(Message message) { | |
JsonObject jsonObject = new JsonObject(); | |
quickfix.Message.Header header = message.getHeader(); | |
Iterator<quickfix.Field<?>> headerIterator = header.iterator(); | |
while (headerIterator.hasNext()) { | |
quickfix.Field<?> field = headerIterator.next(); | |
String name = tagToNameMap.get(field.getTag()); | |
if (name == null) { | |
name = String.valueOf(field.getTag()); | |
} | |
try { | |
jsonObject.addProperty(name, header.getString(field.getTag())); | |
} catch (FieldNotFound fieldNotFound) { | |
// ignore, should not happen | |
} | |
} | |
Iterator<quickfix.Field<?>> bodyIterator = message.iterator(); | |
while (bodyIterator.hasNext()) { | |
quickfix.Field<?> field = bodyIterator.next(); | |
String name = tagToNameMap.get(field.getTag()); | |
if (name == null) { | |
name = String.valueOf(field.getTag()); | |
} | |
try { | |
jsonObject.addProperty(name, message.getString(field.getTag())); | |
} catch (FieldNotFound fieldNotFound) { | |
// ignore, should not happen | |
} | |
} | |
jsonObject.addProperty("RawData", message.toString()); | |
return gson.toJson(jsonObject); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class QuickfixjMessageJsonTransformer { | |
private DataDictionary dataDictionary; | |
public QuickfixjMessageJsonTransformer(){}; | |
public QuickfixjMessageJsonTransformer(DataDictionary dd) { | |
this.dataDictionary = dd; | |
} | |
public String transform(Exchange exchange) { | |
// camel message | |
org.apache.camel.Message in = exchange.getIn(); | |
if (dataDictionary == null) { // the following code doesn't work for FIXT | |
SessionID sessionID = in.getHeader(QuickfixjEndpoint.SESSION_ID_KEY, SessionID.class); | |
Session session = Session.lookupSession(sessionID); | |
dataDictionary = session.getDataDictionary(); | |
} | |
if (dataDictionary == null) { | |
throw new IllegalStateException("No Data Dictionary. Exchange must reference an existing session"); | |
} | |
String jsonStr; | |
try { | |
jsonStr = convertToJSON(dataDictionary, in.getBody(Message.class)); | |
} catch (FieldNotFound | FieldException ex) { | |
throw new IllegalStateException("Cannot convert to JSON", ex); | |
} | |
return jsonStr; | |
} | |
static String convertToJSON(DataDictionary dd, quickfix.Message message) throws FieldNotFound { | |
ObjectMapper mapper = new ObjectMapper(); | |
ObjectNode rootNode = mapper.createObjectNode(); | |
convertFieldMapToJSON(dd, message.getHeader(), rootNode); | |
convertFieldMapToJSON(dd, message, rootNode); | |
convertFieldMapToJSON(dd, message.getTrailer(), rootNode); | |
//rootNode.put("raw", message.toString()); | |
return rootNode.toString(); | |
} | |
private static void convertFieldMapToJSON( | |
DataDictionary dd, | |
FieldMap fieldmap, | |
ObjectNode node | |
) throws FieldNotFound { | |
Field<?> field; | |
String fieldName; | |
int tag; | |
Iterator<Field<?>> fieldIterator = fieldmap.iterator(); | |
while (fieldIterator.hasNext()) { | |
field = fieldIterator.next(); | |
tag = field.getField(); | |
fieldName = dd.getFieldName(tag); | |
if (!isGroupCountField(dd, field)) { | |
if (dd.hasFieldValue(tag)) { // enumerated values | |
node.put(fieldName, dd.getValueName(tag, field.getObject().toString())); | |
} else { | |
if (Number.class.isAssignableFrom(dd.getFieldType(tag).getJavaType())) { | |
node.put(fieldName, fieldmap.getDecimal(tag)); | |
} else { | |
node.put(fieldName, fieldmap.getString(tag)); | |
} | |
} | |
} | |
} | |
Iterator<Integer> groupsKeys = fieldmap.groupKeyIterator(); | |
while (groupsKeys.hasNext()) { | |
int groupTag = groupsKeys.next(); | |
String groupName = dd.getFieldName(groupTag); | |
if (isMarketDataType(node)) { | |
ObjectNode repeatingGroup = node.putObject(groupName); | |
for (Group group : fieldmap.getGroups(groupTag)) { | |
if (group.isSetField(MDEntryType.FIELD)) { | |
ObjectNode groupNode = repeatingGroup.putObject(dd.getValueName(MDEntryType.FIELD, group.getString(MDEntryType.FIELD))); | |
convertFieldMapToJSON(dd, group, groupNode); | |
} else { | |
convertFieldMapToJSON(dd, group, repeatingGroup); | |
} | |
} | |
} else { | |
ArrayNode repeatingGroup = node.putArray(groupName); | |
for (Group group : fieldmap.getGroups(groupTag)) { | |
ObjectNode groupNode = repeatingGroup.addObject(); | |
convertFieldMapToJSON(dd, group, groupNode); | |
} | |
} | |
} | |
} | |
private static boolean isMarketDataType(ObjectNode node) { | |
return Objects.nonNull(node.get("MsgType")) && "\"MarketDataIncrementalRefresh\"".equals(node.get("MsgType").toString()); | |
} | |
private static boolean isGroupCountField(DataDictionary dd, Field field) { | |
return dd.getFieldType(field.getTag()) == FieldType.NUMINGROUP; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment