I am new to FIX. I have a FIX message:
8=FIX.4.4|9=122|35=D|34=215|49=CLIENT12|52=20100225-19:41:57.316|56=B|1=Marcel|11=13346|21=1|40=2|44=5|54=1|59=0|60=20100225-19:39:52.020|10=072|
and I am using quickfixJ.
Here is my class code:
public String getYear(Message aMessage, SessionID aSessionID){
try {
crack(aMessage, aSessionID);
} catch (Exception e) {
e.printStackTrace();
}
String year = String.valueOf(mUTCCal.get(Calendar.YEAR));
String begin = String.valueOf(BeginString);
return year + " " + begin;
}
and when I call this method I 2012 null
I tried all sorts of methods for different fields and I get null. I am confused about why I do not get null for the date and how do I make it interpret correctly the other fields?
quickfix.fix44.NewOrderSingle message;
message = new quickfix.fix44.NewOrderSingle();
SessionID session = new SessionID("beginString", "senderCompID", "targetCompID");
MyApp app = new MyApp("", "", "");
String result = app.myMessage(message, session);
System.out.println(result);
I do not understand where to input the string I have (up top) into message
public void onMessage(Message message, SessionID sessionID) throws FieldNotFound {
Header header = message.getHeader();
String FIX = header.getString(8);
System.out.println(FIX);
}
public void onMessage(quickfix.fix44.NewOrderSingle message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
Header header = message.getHeader();
String FIX = header.getString(8);
String a = message.getString(1);
System.out.println(a);
System.out.println(FIX);}
In order to correctly get and parse FIX messages via QuickFIX, you must:
Create your Application: http://www.quickfixengine.org/quickfix/doc/html/application.html
Implement FromApp(Message message, SessionID sessionID) method
Implement the cracked method for ALL your message types you will receive from your counterparty
The FromApp method can be very simple:
public void fromApp(Message message, SessionID sessionID)
{
crack(message, sessionID);
}
Now, in your example you have a message FIX 4.4 of type 35=D [NewOrderSingle]
Therefore, you MUST implement a method as follows:
public override void onMessage(QuickFix44.NewOrderSingle message, SessionID session)
{
base.onMessage(message, session);
}
Now into your method you can easily work with all the fields you need:
public override void onMessage(QuickFix44.NewOrderSingle message, SessionID session)
{
base.onMessage(message, session);
ClOrdID ordid = new ClOrdID();
message.get(ordid);
}
Please also take a look here: http://www.quickfixengine.org/quickfix/doc/html/receiving_messages.html
Related
I am using WebSocket for making a chat application.
This is the code of my Angular for sending a MessageModel object to backend after converting it into JSON string.
sendMessage(message: MessageModel){
let data = JSON.stringify({
message: message
})
this.ws.send("/messaging/"+message.receiverId, {}, data); }
Now my Java code for receiving the message is:
#MessageMapping("/messaging/{to}")
#SendTo("/inbox/coversation/{to}")
public String processMessageFromClient(#DestinationVariable String to, #Payload String message) throws Exception {
MessageModel msg = new MessageModel();
System.out.println(message);
msg = new Gson().fromJson(message, MessageModel.class);
System.out.println(msg);
return message;
}
OUTPUT of System.out.println(message) is:
{"message":{"messageText":"hey","senderId":4,"senderName":"Akash Malhotra","receiverId":1,"senderEmail":"aku#gmail.com","sentTime":"15:19:43 GMT+0530 (India Standard Time)","date":"08/06/2020, 15:19:43"}}
and
OUTPUT of System.out.println(msg) is:
MessageModel [messageText=null, senderName=null, senderId=null, senderEmail=null, profilePicUrl=null, receiverId=null, sentTime=null, date=null]
QUESTION: The thing I am searching for is a method to set my 'String message' received from angular to my MessageModel object in java since It is showing all the null values.
TL/DR This works
public class StackOverflow
{
public String processMessageFromClient( String to, String message ) throws Exception
{
System.out.println( message );
final MessageWrapper msg = new Gson().fromJson( message, MessageWrapper.class );
System.out.println( msg.message );
return message;
}
public static void main( String[] args ) throws Exception
{
final String jsonString = "{\"message\":{\"messageText\":\"hey\",\"senderId\":4,\"senderName\":\"Akash Malhotra\",\"receiverId\":1,\"senderEmail\":\"aku#gmail.com\",\"sentTime\":\"15:19:43 GMT+0530 (India Standard Time)\",\"date\":\"08/06/2020, 15:19:43\"}}";
new StackOverflow().processMessageFromClient( "You", jsonString );
}
}
class MessageModel
{
String messageText;
String senderName;
Integer senderId;
String senderEmail;
String profilePicUrl;
Integer receiverId;
String sentTime;
String date;
#Override
public String toString()
{
// ... etc.
}
}
class MessageWrapper
{
MessageModel message;
}
Breakdown:
The JSON string contains another wrapper, in the form of:
{
"message" = { /* actual MessageModel contents */ }
}
and since the MessageModel does not contain a field message, no fields are set, resulting in null values.
Wrapping the MessageModel in another class MessageWrapper that does have a field message of type MessageModel, allows GSON to recursively decode the MessageModel.
Pass MessageModel in your method instead of a String. Spring will try to use the underlying jackson (or a custom mapper your set for spring to use) to map the payload to a MessageModel object using the MessageModel class.
#MessageMapping("/messaging/{to}")
#SendTo("/inbox/coversation/{to}")
public String processMessageFromClient(#DestinationVariable String to, #Payload MessageModel message) throws Exception {
...
}
I'm having some issues with Spring LocaleContextHolder.
I have the following code:
public void sendPasswordRecoverySmsAsync(String phone) {
CompletableFuture.runAsync(() -> {
sendPasswordRecoverySmsSync(phone);
});
}
public void sendPasswordRecoverySmsSync(String phone) {
User user = userDao.findByPhone(phone, User.class).orElseThrow(() -> new UserNotFoundException(phone));
log.info("User found, recovering password");
user.setUpdateTime(LocalDateTime.now());
userDao.save(user);
int otp = codesGenerator.generateOtp(user.getUpdateTime());
// Sends the SMS.
Locale locale = LocaleContextHolder.getLocale();
System.out.println("locale " + locale);
String appName = messageSource.getMessage("app.name", null, locale);
String smsContent = messageSource.getMessage("sms.password.recovery", new Object[] { otp }, locale);
Message message = new TextMessage(appName, phone, smsContent);
try {
smsClient.submitMessage(message);
} catch (NexmoClientException | IOException e) {
log.error("Error while sending recovery password message to phone number [{}]", phone, e);
throw new UserActivationException("Error while recovering password for user with phone: " + phone, e);
}
}
and this test:
#Before
public void setup() {
LocaleContextHolder.resetLocaleContext();
Mockito.when(tokenGenerator.generateOtp(Mockito.any())).thenReturn(14);
}
#Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {
// Mocks.
LocaleContextHolder.setLocale(Locale.ENGLISH, true);
String mockPhone = "333";
User mockUser = mockModelBuilder.user(true, true);
Mockito.when(userDao.findByPhone(mockPhone, User.class)).then(r -> {
// TODO
return Optional.of(mockUser);
});
CountDownLatch latch = new CountDownLatch(1);
ArgumentCaptor<TextMessage> messageCaptor = ArgumentCaptor.forClass(TextMessage.class);
Mockito.when(smsClient.submitMessage(messageCaptor.capture())).then(r -> {
latch.countDown();
throw new NexmoClientException();
});
// Test.
service.sendPasswordRecoverySmsAsync(mockPhone);
latch.await();
// Assertions.
Assert.assertTrue(true);
TextMessage actualMessage = messageCaptor.getValue();
Assert.assertEquals("myApp", actualMessage.getFrom());
Assert.assertEquals(mockPhone, actualMessage.getTo());
Assert.assertEquals("Your password recovery code for myApp app is 14", actualMessage.getMessageBody());
}
I would expect the ouput of my test being "en" and this works properly if I launch only this one. However, when I run all my tests, the ouput is "it". This is probably either because in other tests I set an ITALIAN locale or because it's getting the system default.
But why is it getting the wrong one even when I'm resetting it explicitly?
For solely the purpose of testing such localization cases, you might just need to add the following on your test method. This will essentially mark the context Dirty and recreate it, depending on whether you mention as the context being Dirty either before or After the test execution.
#DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
#Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {...
Please refer the documentation here
Hope this helps, as it resolved a similar problem for me.
So I'm using retrofit to execute my API calls, and I have this endpoint which is returning error (which is the desired response), when I try to use my converter to turn the response.errorBody() into my java object Error, it returns the new Error object but its fields are null.
Here's my Error object class:
public class Error {
private final String message;
private final Object objectError;
public Error(String message, Object objectError) {
this.message = message;
this.objectError = objectError;
}
public String getMessage() {
return message;
}
public Object getObjectError() {
return objectError;
}
}
Here's my converter method:
public static Error parseError(Response<?> response) {
Converter<ResponseBody, Error> converter = ApiClient.retrofit().responseBodyConverter(Error.class, new Annotation[0]);
Error error;
try {
error = converter.convert(response.errorBody());
} catch (IOException e) {
return new Error("Connection Error", null);
}
return error;
}
And my JSON response looks alright:
{"status":"error",
"error":{"message":"# is an invalid character",
"objectError":"# is an invalid character"}}
Can you please help me find out what's happening?
Massive thanks!
I finally solved it by creating another class that has the status field and the error field, and used that one in the converter, the error field in that class is the one above.
As the title says, I need a way(no matter if its complicated or not) to create a getData() method that would send request packet to the server > receive the message I already have the system setup but I have a problem with it that I only get the result in PluginMessageReceiveEvent Here's my code with explanations:
public String requestData(String path) {
SocketUtils.sendData("REQUEST|" + p.getPlayer().getUniqueId() + "|" + path, "playerconfig", "BUNGEE");
return /*Need to get data from the plugin message to here*/;
}
#EventHandler
public void onPluginMessageReceive(PluginMessageReceiveEvent e) {
if (e.getChannel().equalsIgnoreCase("playerconfig")) {
String[] args = e.getMessage().split("\\|");
String uuid = args[0];
String path = args[1];//Maybe a HashMap<Path, Data> but that would make the requestData() result return null because you don't get the data instantly.
String data = args[2].replace("_", " ");
if (uuid.equals(p.getPlayer().getUniqueId() + "")) {
return data; //I need to get this result on request data method.
}
}
}
A simple solution is to wait on a lock in the requestData and notify that lock in onPluginMessageReceive. Something like this:
synchronized(this) {
wait();
}
And in your receive method:
synchronized(this) {
notifyAll();
}
Make the data a member field of the class.
Look out for exception handling and syntax errors.
A few of my classes aren't passing automated tests. Unfortunately, said tests do not provide any useful information about why they failed. Here is my code for a couple of the classes. I'd really appreciate it if you could tell me where I went wrong. The comments should explain what each method is supposed to do.
public class CellPhone {
protected String ownerName;
public CellPhone(String owner) {
ownerName = owner;
}
public String receiveCall(CellPhone sender) {
// returns a String of the form:
// owner's name " is receiving a call from " sender's name
String receivingCall = ownerName + " is receiving a call from " + sender;
return receivingCall;
}
public String call(CellPhone receiver) {
// returns a String by using the receiver to invoke receiveCall
// while passing in the current phone
String invokingReceiveCall = receiver.receiveCall(receiver);
return invokingReceiveCall;
}
}
public class TextMessagingPhone extends CellPhone {
private int availMessages;
public TextMessagingPhone(String owner, int messageLimit) {
// invokes the superclass constructor
super(owner);
// sets the new instance variable
availMessages = messageLimit;
}
public TextMessagingPhone(String owner) {
// invokes the other constructor of this class with 15 as the message limit
this(owner, 15);
}
public String receiveText(TextMessagingPhone sender, String message) {
// decreases the number of messages available to send
availMessages--;
// returns a String of the form:
// owner's name " has received TEXT from " sender's name ":" message
String receivedText = ownerName + " has received TEXT from " + sender + ":" + message;
return receivedText;
}
public String sendText(TextMessagingPhone receiver, String message) {
// decreases the number of messages available to send
availMessages--;
// returns a String by using the receiver to invoke receiveText
// while passing in the current phone and the message
String invokingReceiveText = receiver.receiveText(receiver, message);
return invokingReceiveText;
}
}
When a phone makes a call, it passes the receiver as a parameter, so the receiver thinks it is receiving from itself. Also it never gets the name from the passed sender. Try:
public String receiveCall(CellPhone sender) {
// returns a String of the form:
// owner's name " is receiving a call from " sender's name
String receivingCall = ownerName + " is receiving a call from " + sender.getName();
return receivingCall;
}
public String call(CellPhone receiver) {
// returns a String by using the receiver to invoke receiveCall
// while passing in the current phone
String invokingReceiveCall = receiver.receiveCall(this);
return invokingReceiveCall;
}
public String getName() {
return ownerName;
}
public CellPhone(String owner) {
}
You don't assign anything to ownerName...
public CellPhone(String owner) {
ownerName = owner;
}
Check this
String receivingCall = ownerName + " is receiving a call from " + sender;
You are using "sender" which is an object in the string expression. Using sender.ownerName after making it public or defining getOwnerName and using it should work. This same mistake is repeated couple more times!