I got an error in my quickfixj Application. First, I got an error like this:
Out of order repeating group members
After that, I added this text into my initiator.config:
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
But now I got another error in my application:
quickfix.FieldNotFound: Field was not found in message, field=55
at quickfix.FieldMap.getField(FieldMap.java:223)
at quickfix.FieldMap.getString(FieldMap.java:237)
at com.dxtr.fastmatch.marketdatarequestapps.TestMarketdataRequest.fromApp(TestMarketdataRequest.java:38)
at quickfix.Session.fromCallback(Session.java:1847)
at quickfix.Session.verify(Session.java:1791)
at quickfix.Session.verify(Session.java:1862)
at quickfix.Session.next(Session.java:1047)
at quickfix.Session.next(Session.java:1204)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:163)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:113)
at quickfix.mina.SingleThreadedEventHandlingStrategy.lambda$blockInThread$1(SingleThreadedEventHandlingStrategy.java:145)
at quickfix.mina.SingleThreadedEventHandlingStrategy$ThreadAdapter$RunnableWrapper.run(SingleThreadedEventHandlingStrategy.java:267)
at java.lang.Thread.run(Thread.java:748)
My code for get value of symbols is :
public void fromApp(quickfix.Message message, SessionID sessionID)
throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
try {
String symbol = message.getString(Symbol.FIELD);
System.out.println(" FromApp " + message);
message.getString(TransactTime.FIELD);
// String seqNo = message.getString(MsgSeqNum.FIELD);
double bid = message.getDouble(MDEntryPx.FIELD);
double ask = message.getDouble(MDEntryPx.FIELD);
// System.out.println(seqNo + " " + message);
} catch (FieldNotFound fieldNotFound) {
fieldNotFound.printStackTrace();
}
}
I have also using this code
public void onMessage (MarketDataIncrementalRefresh message, SessionID sessionID) throws FieldNotFound{
try
{
MDReqID mdreqid = new MDReqID();
SendingTime sendingtime = new SendingTime();
NoMDEntries nomdentries = new NoMDEntries();
quickfix.fix42.MarketDataIncrementalRefresh.NoMDEntries group
= new quickfix.fix42.MarketDataIncrementalRefresh.NoMDEntries();
MDUpdateAction mdupdateaction = new MDUpdateAction();
DeleteReason deletereason = new DeleteReason();
MDEntryType mdentrytype = new MDEntryType();
MDEntryID mdentryid = new MDEntryID();
Symbol symbol = new Symbol();
MDEntryOriginator mdentryoriginator = new MDEntryOriginator();
MDEntryPx mdentrypx = new MDEntryPx();
Currency currency = new Currency();
MDEntrySize mdentrysize = new MDEntrySize();
ExpireDate expiredate = new ExpireDate();
ExpireTime expiretime = new ExpireTime();
NumberOfOrders numberoforders = new NumberOfOrders();
MDEntryPositionNo mdentrypositionno = new MDEntryPositionNo();
message.getField(nomdentries);
message.getField(sendingtime);
message.getGroup(1, group);
int list = nomdentries.getValue();
for (int i = 0; i < list; i++)
{
message.getGroup(i + 1, group);
group.get(mdupdateaction);
if (mdupdateaction.getValue() == '2')
System.out.println("Enter");
group.get(deletereason);
group.get(mdentrytype);
group.get(mdentryid);
group.get(symbol);
group.get(mdentryoriginator);
if (mdupdateaction.getValue() == '0')
group.get(mdentrypx);
group.get(currency);
if (mdupdateaction.getValue() == '0')
group.get(mdentrysize);
}
System.out.printf("Got Symbol {0} Price {1}",
symbol.getValue(), mdentrypx.getValue());
}catch (Exception ex)
{
System.out.println("error" + ex);
}
but i also get error like this
quickfix.FieldNotFound: Field was not found in message, field=55
at quickfix.FieldMap.getField(FieldMap.java:223)
at quickfix.FieldMap.getString(FieldMap.java:237)
at com.dxtr.fastmatch.marketdatarequestapps.TestMarketdataRequest.fromApp(TestMarketdataRequest.java:39)
at quickfix.Session.fromCallback(Session.java:1847)
at quickfix.Session.verify(Session.java:1791)
at quickfix.Session.verify(Session.java:1862)
at quickfix.Session.next(Session.java:1047)
at quickfix.Session.next(Session.java:1204)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:163)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:113)
at quickfix.mina.SingleThreadedEventHandlingStrategy.lambda$blockInpacket_write_wait: Connection to 3.13.235.241 port 22: Broken pipe
and here the value i check in my message.log
8=FIX.4.2^A9=0217^A35=X^A34=7291^A49=Fastmatch1^A52=20200401-10:47:59.833^A56=MDValueTrade2UAT1^A262=VT_020^A268=02^A279=2^A55=GBP/CHF^A269=0^A278=1140851192^A270=1.19503^A271=02000000^A279=0^A55=GBP/CHF^A269=0^A278=1140851194^A270=1.19502^A271=06000000^A10=114^A
my broker have send to me the price and etc
My question is: how to fix my problem from this code ?
First, I got an error like this:
Out of order repeating group members
Your data dictionary doesn't match your counterparty's. Fix that and this will go away.
After that, I added this text into my initiator.config:
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
This did not fix anything -- it HIDES your actual problem and has you looking at a new fake problem.
What you need to do:
Your configuration has this, right?
UseDataDictionary=Y
DataDictionary=path/to/FIXnn.xml
# or if FIX5:
AppDataDictionary=path/to/FIX5n.xml
TransportDataDictionary=path/to/FIXT.xml
Find your counterparty's documentation, and make sure your xml file's messages and fields match what they say they're going to send you. Make sure all repeating groups have the same fields in the same order.
Here is some documentation about how the Data Dictionary xml file is structured. It's pretty easy.
Related
I am setting up the Backend code of a chat messaging system for an app my group is creating using WebSockets. My goal is for our app to be able to send and receive messages in a public group chat, and also specifically Direct Message (DM) specific people with an # symbol, in front of the recipient's username.
I managed to get the public group messaging component working perfectly fine. However, I am running into an issue with the DM functionality. Let's say for example a person named "test" wrote a message to someone named "teacher" and here was what they typed: "#teacher testMessage". Ideally, I would want the program to send the message "testMessage" to "teacher" only. However, every time I would test the program using Postman, I would end up with the following error:
java.lang.NullPointerException: Cannot invoke "javax.websocket.Session.getBasicRemote()" because the return value of "java.util.Map.get(Object)" is null
From my understanding, the error means that the variable type the method is supposed to receive (in this case a String), is not what it is actually getting.
Here is the code below:
private static Map < Session, String > sessionUsernameMap = new Hashtable<>();
private static Map < String, Session > usernameSessionMap = new Hashtable<>();
#OnMessage
public void onMessage(Session session, String message) throws IOException { //The message is the the entire thing that the person types (ex: #teacher testMessage)
logger.info("Message Received: " + message); //String message = #teacher testMessage
String username = sessionUsernameMap.get(session); //String username = "test" This is the username of the person who wrote the message
if (message.startsWith("#")) {
String destUsername = message.split(" ")[0].substring(1); //destUsername = "teacher"
String realMessage = message.substring(message.lastIndexOf(" ") + 1); //realMessage = "testMessage"
sendMessageToParticularUser(destUsername, "[DM] " + username + ": " + realMessage); //puts in "teacher" for destUsername and "testMessage" for realMessage
sendMessageToParticularUser(username, "[DM] " + username + ": " + message);
}
else {
broadcast(username + ": " + message);
}
msgRepo.save(new Message(username, message));
}
private void sendMessageToParticularUser(String username, String message) {
System.out.println(message);
try {
usernameSessionMap.get(username).getBasicRemote().sendText(message); //PROBLEM RIGHT HERE WITH .get(username)
} catch (IOException e) {
logger.info("Exception: " + e.getMessage().toString());
e.printStackTrace();
}
}
I have been working on this issue for a few hours now with no luck. I would very much appreciate any help or input on this. Thank you.
so as part of some work I've been doing I was given a file with WebServices that are being used in a Swift application. I have zero familiarity with WebServices and only know Java through syntax understanding. I need to call one of these gets with a parameter from the swift application. What I'm trying to figure out first and foremost is how I can call one of these webservices with a parameter from the URL it's associated with. For example down below I want to call the method
http://localhost:9000/ListVehicleByPlateNumber
and I want to specify the parameter through the URL say something like
http://localhost:9000/ListVehicleByPlateNumber?para="123"
But this doesn't assign any value to the parameter and I'm not getting results. If I hardcode so that the string used in the function is = "123" it gives me the results I'm looking for. I just need to know how I can pass this parameter through the url, syntax-wise.
Routes file
GET /ListVehicleByPlateNumber controllers.NewVehicle.listVehicleByPlateNumber(para: String ?="")
Controller
public Result listVehicleByPlateNumber(String para){
NewVehicleModel v = new NewVehicleModel();
List<NewVehicleModel> vehiclesC = v.searchByPlateVehicle(para);
ObjectNode wrapper = Json.newObject();
ObjectNode msg = Json.newObject();
if(vehiclesC != null) {
msg.set("VehicleList", toJson(vehiclesC));
wrapper.set("success", msg);
return ok(wrapper);
}else{
msg.put("error", "There are no vehicles with the plate number");
wrapper.set("error", msg);
return badRequest(wrapper);
}
}
Where it's called
public List<NewVehicleModel> searchByPlateVehicle(String plateNumber){
Transaction t = Ebean.beginTransaction();
List<NewVehicleModel> vehicles = new ArrayList<>();
try {
String sql = "SELECT V.idNewVehicle, V.VehicleType,V.PlateNumber,V.VehicleJurisdiction,V.State,V.Vin,V.Year, " +
"V.Make,V.modelos,V.RegistrationNumber,V.InsuranceCompany,V.PurchaseDate,V.ExpirationDate,V.idPersonaFK " +
"FROM NewVehicle V " +
"WHERE V.PlateNumber = :plateNumber";
RawSql rawSql = RawSqlBuilder.parse(sql)
.columnMapping("V.idNewVehicle", "idNewVehicle")
.columnMapping("V.State", "state")
.columnMapping("V.VehicleType", "vehicleType")
.columnMapping("V.PlateNumber", "plateNumber")
.columnMapping("V.VehicleJurisdiction", "vehicleJurisdiction")
.columnMapping("V.Vin", "vin")
.columnMapping("V.Year", "year")
.columnMapping("V.Make", "make")
.columnMapping("V.modelos", "modelos")
.columnMapping("V.RegistrationNumber", "registrationNumber")
.columnMapping("V.InsuranceCompany", "insuranceCompany")
.columnMapping("V.PurchaseDate", "purchaseDate")
.columnMapping("V.ExpirationDate", "expirationDate")
.columnMapping("V.idPersonaFK", "idPersonaFK")
.create();
Query<NewVehicleModel> query = Ebean.find(NewVehicleModel.class);
query.setRawSql(rawSql)
.setParameter("plateNumber", plateNumber);
vehicles = query.findList();
t.commit();
}
catch (Exception e){
System.out.println(e.getMessage());
}finally {
t.end();
}
return vehicles;
}
Found my own answer. I ended up casting from Integer to String here's how it looks in routes
GET /ListVehicleByPlateNumber/:para controllers.NewVehicle.listVehicleByPlateNumber(para: Integer )
Controller
public Result listVehicleByPlateNumber(int para){
String p = String.valueOf(para);
URI Format for value 123 example.
http://localhost:9000/ListVehicleByPlateNumber/123
I have a question about mapping, map key and map values.
I am writing a chat program : I have a problem to add a message. I can't add a message. That puts me in a empty web page with an error(can't see the number and reason of error)
Can you tell me where is the problem ?
// add a message to a chatroom
#RequestMapping(value="/addMessageSalon/{salon}/{pseudo}/{message}", method = {RequestMethod.GET, RequestMethod.POST})
public String addMessageSalon(HttpServletRequest request, #PathVariable("salon") String chatroom, #PathVariable("pseudo") String username, #PathVariable("message") String message) {
Message mes = null;
mes.setMessage(message);
mes.setPseudo(username);
GestionMessages addition = (GestionMessages)request.getSession().getServletContext().getAttribute("gestionMessages");
Map<String, ArrayList<Message>> resultat = addition.getMessages();
Iterator<Map.Entry<String, ArrayList<Message>>> entries = resultat.entrySet().iterator();
// iteration
while(entries.hasNext()) {
Map.Entry<String, ArrayList<Message>> entry = entries.next();
if(!entries.hasNext() && !entry.getKey().contains(chatroom)) {
// if chatroom does not exist, we give an error
throw new IllegalArgumentException("Chatroom '" + chatroom + "' doesn't exist");
}
if(entry.getKey().contains(chatroom)){
ControleurPrincipal.getUsersInDataBase().add(username);
addition.getMessagesSalon(chatroom).add(mes);
break;
}
}
resultat = addition.getMessages();
return "redirect:/";
}
First of all:
Message mes = null;
mes.setMessage(message);
This will throw a NullPointerException, every time. So either that's the error you're getting, or that is not your code.
If that's your actual code, then you need to instantiate Message first, like this:
Message mes = new Message();
Instead of doing this
if(!entries.hasNext() && !entry.getKey().contains(monSalon)) {
you might want to do
if(!resultat.contains(monSalon)) {
and do it before the while.
I am trying to read IRC and pull data from individual IRC messages in Processing. You can see the code (also with twitter library, ignore that) and I need some pointers on how I can pull the data out in the format of Nick:Message so it can be displayed in a visualization.
//Twitter
import twitter4j.conf.*;
import twitter4j.*;
import twitter4j.auth.*;
import twitter4j.api.*;
import java.util.*;
// Import the net libraries
import processing.net.*;
// Declare a client
Client client;
Twitter twitter;
String searchString = "god";
List<Status> tweets;
String server = "irc.twitch.tv";
String nick = "NugShow";
//String user = "simple_bot";
int port = 6667;
String channel = "#nugshow";
String password = "xx";
String in = "butt";
String checkFor;
//bools
Boolean isLive = false;
int privMsgIndex;
int atIndex;
String playerSubstring;
// The channel which the bot will joString channel = "#irchacks";
int currentTweet;
void setup()
{
size(800,600);
frameRate(60);
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("xx");
cb.setOAuthConsumerSecret("xx");
cb.setOAuthAccessToken("xx");
cb.setOAuthAccessTokenSecret("xx");
TwitterFactory tf = new TwitterFactory(cb.build());
twitter = tf.getInstance();
getNewTweets();
currentTweet = 0;
thread("refreshTweets");
thread("loopChat");
connectToServer();
//IRC
}
void draw()
{
if (client.available() > 0) {
String in = client.readString();
println(in);
}
if (isLive == false){
if (client.available() > 0) {
}
} else {
}
/*
fill(0, 40);
rect(0, 0, width, height);
currentTweet = currentTweet + 1;
if (currentTweet >= tweets.size())
{
currentTweet = 0;
}
Status status = tweets.get(currentTweet);
fill(200);
text(status.getText(), random(width), random(height), 300, 200);
delay(100);
*/
}
void joinChannel() {
String in = client.readString();
client.write( "JOIN " + channel + "\n\r" );
client.clear();
in = client.readString();
println(in);
if (in != null){
//println("Recieved data");
println(in);
//String inString = myClient.readStringUntil("");
isLive = true;
println(isLive);
}
}
void connectToServer()
{
client = new Client(this, server , 6667);
client.write( "PASS " + password + "\n\r" );
println(password + " sent!");
client.write( "NICK " + nick + "\n\r" );
println(nick + " sent!");
joinChannel();
}
void getNewTweets()
{
try
{
Query query = new Query(searchString);
QueryResult result = twitter.search(query);
tweets = result.getTweets();
}
catch (TwitterException te)
{
System.out.println("Failed to search tweets: " + te.getMessage());
System.exit(-1);
}
}
void refreshTweets()
{
while (true)
{
getNewTweets();
println("Updated Tweets");
delay(30000);
}
}
void loopChat()
{
while (true)
{
if (privMsgIndex != 0){
println(privMsgIndex);
//privMsgIndex = privMsgIndex - 15;
atIndex = in.indexOf("#");
println(atIndex);
//atIndex = atIndex + 1;
playerSubstring = in.substring(atIndex, privMsgIndex);
println(playerSubstring);
} else {
println("looped");
}
delay(300);
client.clear();
in = null;
}
}
void keyPressed()
{
}
void tweet()
{
try
{
Status status = twitter.updateStatus("This is a tweet sent from Processing!");
System.out.println("Status updated to [" + status.getText() + "].");
}
catch (TwitterException te)
{
System.out.println("Error: "+ te.getMessage());
}
}
The chat commands look like this: :nugshow!nugshow#nugshow.testserver.local PRIVMSG #nugshow :dddd where nugshow is the username, #nugshow is the channel, and dddd is the message. I need to get it into the format of nugshow: dddd.
there is a lot of header information that I'm not sure how to strip out of client.recieved buffer as well, it looks like this:
:testserver.local 001 nugshow :Welcome, GLHF!
:testserver.local 002 nugshow :Your host is testserver.local
:testserver.local 003 nugshow :This server is rather new
:testserver.local 004 nugshow :-
:testserver.local 375 nugshow :-
:testserver.local 372 nugshow :You are in a maze of twisty passages, all alike.
:testserver.local 376 nugshow :>
:nugshow!nugshow#nugshow.testserver.local JOIN #nugshow
:nugshow.testserver.local 353 nugshow = #nugshow :nugshow
:nugshow.testserver.local 366 nugshow #nugshow :End of /NAMES list
:jtv!jtv#jtv.testserver.local PRIVMSG nugshow :HISTORYEND nugshow
I would not recommend regex here. At least not if you want to be able to catch all types of IRC messages. The key is to look at the message code to know what you can actually get out of the message. As I'm also writing an IRC-client (just for giggles) I have some notes for you.
Be sure to answer any PINGs that the server sends you so you don't get kicked off. As the PING is sent with an identifier, you need to catch that and send it back. A simple way to do this is to check the last line that was sent from the server and substring it.
String line = inputStream.readLine();
if(line.substring(0,4).equals("PING")){
send("PONG " + line.substring(5)); // Assume you have some send-function.
}
This will make sure you don't get kicked off and can proceed to actually stay on a server.
As I mentioned, I do not recommend using regex for this as it would become a RegEx-of-doom. So, what I have done is to just split the line you get and put all the results in a String array.
String[] arr = line.split(" ");
As you know by your own message line you have posted, the IRC protocol separates things with spaces. So splitting at spaces in not all that shabby (we'll get how to deal with actual text in a bit).
The basic structure that is always the same (as far as I can tell) in messages is PREFIX COMMAND PARAM PARAM/TRAILING. So what does this mean? The PREFIX is where the message was sent from. Example ":user!user#host.com". The COMMAND is what the line actually is. You are looking for PRIVMSG here, but there are many, many, others that you might want to take care of. Like JOIN, PART, QUIT, 332 (current topic), 353 (nicks in channel, 404 (unable to send to channel), etc. etc. The PARAM and PARAM/TRAILING will all depend on the COMMAND.
So, what do we gain from splitting at spaces? This:
arr[0] = :user!user#host.com
arr[1] = COMMAND
arr[2] = PARAM
arr[3 onwards] = rest
We can now easily manage every command in it's own needed way.
Without further delay, lets get to your actual question, the PRIVMSG.
I will use this string: ":Chewtoy!chewtoy#stackoverflow.com PRIVMSG #stackoverflow :Ty: I saw your question and thought I should give you an answer."
After doing a split at the spaces, we get the array
arr[0] = :Chewtoy!chewtoy#stackoverflow.com
arr[1] = PRIVMSG
arr[2] = #stackoverflow
arr[3] = :Ty:
arr[4] = I
arr[5] = saw
...
As you can see, everything from 3 and onwards is the message you want. 0-2 is stuff that you need to be able to know who sent what where. My code for getting all this looks like this:
String[] arr = receivedLine.split(" ");
if(arr[1].equals("PRIVMSG")){
String[] usr = arr[0].split(!"); // Get the user, which is in usr[0]. Host in usr[1]
StringBuilder msg = new StringBuilder();
for(int i=3; i<arr.length; i++){ // We know the message starts at arr[3], so start counting from that.
msg.append(arr[i] + " ");
}
String chan = "";
if(arr[2].substring(0,1).equals("#")){ // We need to differentiate between sending to channel and sending a PM. The only difference in this is where the text is sent.
chan = arr[2];
} else{
chan = usr[0].substring(1); // substring(1) because we want Chewtoy, not :Chewtoy
}
// The result here will be:
// <#stackoverflow> Chewtoy: Ty: I saw your question and thought I should give you an answer.
sendItAllToWhereYouWantIt("<" + chan +"> " + usr[0].substring(1) + ": " + msg.substring(1));
}
Hope that helps.
I have this code. And basically this returns the correct data without the town qualities. When I add the town qualities the method returns nothing, not even the orginal data that it has been and I dont know why. Can anyone see a problem?
protected void listRecords() {
mListForm.deleteAll(); // clear the form
try {
RecordStore rs = RecordStore.openRecordStore("Details", true);
RecordEnumeration re = rs.enumerateRecords(null, new RecordSorter(), false);
while (re.hasNextElement()) {
byte [] recordBuffer = re.nextRecord();
String record = new String(recordBuffer);
// extract the name and the age from the record
int endOfName = record.indexOf(";");
int endOfDesc = record.indexOf(";" , endOfName + 1);
int endOfTown = record.indexOf (";", endOfDesc + 1);
String name = record.substring(0, endOfName);
String desc = record.substring(endOfName + 1, endOfDesc);
String town = record.substring(endOfDesc +1, endOfTown);
mListForm.append(name + " aged: "+ desc + " " + town);
}
rs.closeRecordStore();
}
catch(Exception e){
mAlertConfirmDetailsSaved.setString("Couldn't read details");
System.err.println("Error accessing database");
}
mDisplay.setCurrent(mListForm);
}
Have you tried running it in the debugger? Is the exception happening? Are the three semicolons present in the record? Is there a limit on mDisplay's string size? When setCurrent is called, is the mListForm correct?
In other words, what have you done so far and where is it definitely right, and where does it become wrong?