how to accept fixed length message by spring rest api - java

I need to expose one rest API with spring boot that has to accept message content in fixed-length format and, as is(i.e without disturbing fixed-length message content ), need to put into IBM MQ to pass received fixed-length message to the back end system (IBM mainframe system)via IBM MQ
I would be requesting you to help me with the sample code for this requirement
Fixed-length format messages, for example:
20011228YF2001122814313425 Forest St Marlborough MA017525083828200600
Fixed-length format messages use ordinal positions, which are offsets to identify where fields are within the record. There are no field delimiters. An end-of-record delimiter is required, even for the last record.

Welcome stackoverflow asking question area. As I see this is more into javax.validation.constraints package. In your entity, you do something like
public class Market {
#NotNull
#Size(max=4)
private String marketCode;
// getters/setters
}
So when you try to bind values from #RequestBody Market market, it will throw error regarding the length

Related

Remove a document from Mongo DB with Apache Camel

My main issue might be not understanding some conventions in the Camel documents.
https://camel.apache.org/components/latest/mongodb-component.html#_delete_operations
They have a camel route commented out, and two Java objects being defined, which are not commented out. What are they trying to indicate? Where are these objects at in a project?
Anyway, I'm subscribed to a JMS queue that I have another camel route publishing to. The message is a JSON string, which I save to a Mongo DB. But what I'd like to do is remove any current documents (based on criteria) and replace it with the new message.
from("jms:topic:orderbook.raw.feed")
.log("JMS Message: ${body}")
.choice()
.when().jsonpath("$.[?(#.type=='partial')]")
// Figure out how to delete the old orderbook from Mongo with a type=T1
.to("mongodb:mongo?database=k2_dev&collection=orderbooks&operation=save");
Does your orderbook have an ID? If so, you can enrich the JSON with an _id field (MongoDB default representation for identifiers) whose value would be that ID. Thus you'll be "upserting" that orderbook.
Obs.: Sure the Camel docs could be better.
But if you really feel you'd have to perform a remove operation before saving an orderbook, another option would be to extract its type from the current JSON string and use it as a filter when removing. Something like:
from("jms:topic:orderbook.raw.feed")
.log("JMS Message: ${body}")
.filter("$.[?(#.type=='partial')]")
.multicast().stopOnException()
.to("direct://orderbook-removal")
.to("direct://orderbook-save")
.end()
;
from("direct://orderbook-removal")
// extract type and set it as the body message. e.g. {"type":"T1"}
.to("mongodb:mongo?database=k2_dev&collection=orderbooks&operation=remove")
;
from("direct://orderbook-save")
.to("mongodb:mongo?database=k2_dev&collection=orderbooks&operation=save")
;
The multicast sends a copy of the message to each destination. So the content won't be affected.

Issue with Forwarded Header and Multiple Values in Spring

According to the RFC7239 specification, syntax for Forwarded Header is as follows:
Forwarded: by=<identifier>;for=<identifier>;host=<host>;proto=<http|https>
These values are used by Spring (all recent versions), if present, in order to reflect the client-originated protocol and address (when allowed through a configuration). There is a problem when using multiple values in this header:
# Multiple values can be appended using a comma
Forwarded: for=192.0.2.43,for=198.51.100.17;proto=https;host=xxx.yyy.com;by=10.97.9.10
The code in UriComponentsBuilder#adaptFromForwardedHeaders:798-800 gets the first Forwarded Header, if multiple are found, splits it by comma and uses only the first part:
UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
try {
String forwardedHeader = headers.getFirst("Forwarded");
if (StringUtils.hasText(forwardedHeader)) {
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
....
}
Using the example above, the forwardedToUse variable becomes Forwarded: for=192.0.2.43 where all useful information is trimmed.
Is this really an issue or there is something that I am missing? And if this is really a problem, how can I deal with it.
Thanks a lot in advance!
It seems that there is an issue in Spring with Forwarded header in case of multiple values. It is fixed with the commit below and will be available in next release:
GitHub Issue: Issue with Forwarded Header and Multiple Values
Spring Framework Commit: Do not tokenize Forward header value
Release: Spring 5.2.9.RELEASE

Fetching string value from JMS header

I'm trying to figure out how to pull a value out of a JMS header so I can route it to a specific queue dynamically. I have spent hours trying various methods to extract the value but I haven't been successful. See the below snippet which explains what I'm after. Any help or even pointing me in the right direction would be much appreciated.
// fetch the queue name from the JMS header
String queue = "jms:queue:" + header("__DestinationQueue").toString();
choice = choice
.when(header("Match").isEqualTo("true"))
.id("JMSDaemonOutboundRouteBuilder")
.to(queue);
choice = choice
.otherwise().bean(UnroutableMessageLogAction.class)
.bean(EndConversationAction.class, "process")
.bean(ESBMessageCompleteAction.class, "process")
.to("jms:queue:UNROUTED").endChoice();
The data is definitely contained in the header (I've run .isEqualTo comparisons on the header value to confirm this) I am just having issues extracting the actual value into the string.
The solution was to use toD instead of to which natively allows routing to JMS header values. Link below:
http://camel.apache.org/message-endpoint.html

Parse and create message from config file/database/property file at run time

In my application perticular message structure/format are send and received. When I have to send the message, the message should be created on the particular format. I have parse message on perticular message. The message nothing but byte array
To parse the message I have used Preon lib.
I have following problem with :
Programatically I have to create the byte array for each field.
When message format get changed I have to change the code.
How can I construct run time message structure and parse the message structure.
The message structure look like this
Message1{
int field_1
char[2] field_2
long filed_3
double filed_4
bit field_5
short field_6
char field_7
}
Message2{
Message1 msg
short field_8
char field_9
}
Message structure will be change any time.
There are more than 1000 types of messages in the system.
So I am looking for solution in java which will create message and parse from given structure runtime.
If you have sample code, please provide the code sniipet.
I would use an OSGi container (karaf/iPOJO) which allows me to change the code while the application is running. This means you can add fields, change their type and size while the system without bringing down the application.
Note: if you add a field or make a field larger but the code doesn't support it won't you lose information?

Handling multiple parameters in a URI (RESTfully) in Java

I've been working on a small scale web service in Java/Jersey which reads lists of user information from clients contained in XML files. I currently have this functioning in all but one aspect: using multiple parameters in the URI to denote pulling multiple sets of user information or multiple sets of client information. I have a version which currently works, but is not the best way nor what the project description calls for.
Currently, my code looks like this:
#Path("Client/{client}/users")
public class UserPage
{
#GET
#Produces(MediaType.TEXT_HTML)
public String userChoice(#PathParam(value = "client") final String client)
{****Method here which handles a list of 'users'****}
#GET
#Path("{name}")
#Produces(MediaType.TEXT_HTML)
public String userPage(#PathParam(value = "client") final String client, #PathParam(value = "name") final String name)
{****Method here which handles 'user' information****}
The first method handles a list of users from a 'client' denoted by "{client}" in the URI. The second method delivers 'user' information denoted by "{name}" in the URI. Both will function with a single argument. Currently, in order to handle multiple 'users' I have "{name}" comma separated like "Client/Chick-Fil-A/users/Phil,Bradley". I can parse this after using #PathParam and create an array of these 'users', but again, I feel this is not the best way to handle this, and the project description calls for something different.
Is there a way to accomplish this same task with a URI formatted as "Client/Chick-Fil-A;cd=Phil,Bradley"? (The ;cd= is what's giving me the most trouble.)
I also need to be able to use this format for multiple clients, i.e. "Client;cd=Chick-Fil-A,Subway/users;cd=Phil,Bradley".
Edit: To clarify the project:
The client information is contained in 6 separate files. Each of these files has the same 3 users (this is a proof of concept, effectively). I need to be able to pull different subsets of information, for instance, user Phil from McDonalds and Chick-Fil-A, or users Phil and Peter from McDonalds, or users named Peter from all clients, etc.
You cannot use '=' in the URL path since it's a reserved character. However there are many other character you can use as delimiters such as '-' and ','. So instead of '=' you can use '-'. If you really really want to use '=' then you will have to URL-encode it; however, I would strongly recommend against this because it may make things more complicated then it should be.
You can see the grammar of the URL string here:
http://www.w3.org/Addressing/URL/url-spec.txt
Copy and search the following string to skip to the path grammar:
path void | segment [ / path ]
segment xpalphas
That said, I believe HTTP request is usually used for request single resource only. So my personal opinion is to not implement the service the way you implemented. For getting multiple clients I would use query parameters as filters like this:
Client/{cName}/users?filters=<value1>,<value2> ...
Edit: From the business case you got there, it seems like you probably need service like
/users?<filters>
/clients?<filters>
So say you want to get Peter from all clients then can have a request of this form:
/users?name=Peter
Similarly, if you want to get Jack and Peter from Starbucks then you can do:
/users?name=Peter,Jack&client=Starbucks
Hopefully this helps.
Query strings have the following syntax and you can have multiple parameters with the same name:
http://server/path/program?<query_string>
where query_string has the following syntax:
field1=value1&field1=value2&field1=value3…
For more details check out this entry in Wikipedia: http://en.wikipedia.org/wiki/Query_string

Categories

Resources