How to get instance of current message bein processed in cxf? - cxf

I want to get the ID of the Inbound message in my implemented service end point which has following parameters available:
Custom JAXB Request
#Context HttpServletRequest
e.g. From below inbound message i want to retrieve ID: 1 in my service endpoint.
INFO: Inbound Message
ID: 1
Address:
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/xml
Headers:
Payload:
Can anyone please tell me if there is a way to get that ID ?

You can get the current CXF Message using PhaseInterceptorChain.getCurrentMessage(). The logging ID used by the logging interceptors is stored in the Message Map, and can be retrieved with its key, e.g.
String loggingId = (String) PhaseInterceptorChain.getCurrentMessage().get(LoggingMessage.ID_KEY);

Related

How to get AMQP Message properties in Apache Camel AMQP Component

I have a Springboot application using Apache Camel AMQP component to comsume messages from a Solace Queue. To send a message to the Queue I use Postman and the Solace REST API. In order to differentiate the message type I add Content-Type to the header of the Http request in Postman. I used SDKPerf to check the message header consumed from solace and the message header is found under "HTTP Content Type" along with other headers.
However, I can't seem to find a way to get this Content-Type from Camel Side. In the documentation it says
String header = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
However this always produces null. Any Ideas how to get the message properties in Camel?
EDIT: I think it's actually due to the fact that Camel is using QPid JMS, and there is no JMS API way of getting the Content Type, it's not in the spec. Even though AMQP 1.0 does support content-type as a property. But yeah, my suggestion of a custom property below is still probably the way I would go.
https://camel.apache.org/components/3.20.x/amqp-component.html
https://www.amqp.org/sites/amqp.org/files/amqp.pdf
Edited for clarity & corrections. TL/DR: use a custom user property header.
The SMF Content Type header in the original (REST) message is passed through to the consumed AMQP message as a property content-type, however the JMS API spec does not expose this; there is no way in standard JMS to retrieve this value. It is, however, used by the broker to set the type of message (e.g. TextMessage). Check "Content-Type Mapping to Solace Message Types" in the Solace docs.
Using Solace's SDKPerf AMQP JMS edition to dump the received message to console (note this uses QPid libraries):
./sdkperf_jmsamqp.sh -cip=amqp://localhost:5672 -stl=a/b/c
-md -q
curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Content-Type: text'
^^^^^^^^^^^^^^^^^^ Start Message ^^^^^^^^^^^^^^^^^^^^^^^^^^^
JMSDeliveryMode: PERSISTENT
JMSDestination: a/b/c
JMSExpiration: 0
JMSPriority: 4
JMSTimestamp: 0
JMSRedelivered: false
JMSCorrelationID: null
JMSMessageID: null
JMSReplyTo: null
JMSType: null
JMSProperties: {JMSXDeliveryCount:1;}
Object Type: TextMessage
Text: len=5
hello
The header does not get mapped through, but does get used to set the message type. If I remove that HTTP header, the received AMQP message is binary. But since other types of Content-Types also map to TextMessages (e.g. application/json, application/xml, etc.), the fact you're receiving a TextMessage is not enough to infer exactly what Content-Type you published your REST message with.
For completeness, I used WireShark with an AMQP decoder, and you can see the header present on the received AMQP message:
Frame 3: 218 bytes on wire (1744 bits), 218 bytes captured (1744 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 5672, Dst Port: 60662, Seq: 2, Ack: 1, Len: 174
Advanced Message Queueing Protocol
Length: 174
Doff: 2
Type: AMQP (0)
Channel: 2
Performative: transfer (20)
Arguments (5)
Message-Header
Durable: True
Message-Annotations (map of 1 element)
x-opt-jms-dest (byte): 1
Message-Properties
To: a/b/c
Content-Type: text <----------
Application-Properties (map of 1 element)
AaronEncoding (str8-utf8): CustomText
AMQP-Value (str32-utf8): hello
So my suggestion is this:
Set an additional custom header, a User Property, which will get passed through to the AMQP message:
curl http://localhost:9000/TOPIC/a/b/c -d 'hello' -H 'Solace-User-Property-AaronEncoding: CustomText' -H 'Content-Type: text'
JMSDestination: a/b/c
JMSProperties: {AaronEncoding:CustomText;JMSXDeliveryCount:1;}
Object Type: TextMessage
Text: len=5
hello
My always-goto guide for Solace REST interactions: https://docs.solace.com/API/RESTMessagingPrtl/Solace-REST-Message-Encoding.htm
Hope that helps!
It may have a different name in Camel. Try either printing all the headers or stop it in the debugger and examine the incoming message.

Unable to access the access code and refresh token of AAD Microsoft App

I'm trying to automate the file transfer between one drive and Linux. Hence I need to generate the access token and refresh token.
My POST URL is
https://login.microsoftonline.com/common/oauth2/v2.0/token?grant_type='authorization_code'&client_id=XXXXXXXXXXXXXX&code=XXXXXXXXXXXXX
getting below error as below
{
"error": "invalid_request",
"error_description": "AADSTS9001442323: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 55c2b449-381b-41844ads5a2f-b2b7-451d65188500\r\nCorrelation ID: bf082e8f-99be-41e0-87dd-756894601365\r\nTimestamp: 2020-04-27 17:54:21Z",
"error_codes": [
90043234144
],
"timestamp": "2020-04-27 17:54:21Z",
"trace_id": "55cadsasdad2b449-381b-412f-b2b7-451d65188500",
"correlation_id": "bf0asdadada82e8f-99be-41e0-87dd-75688dasda94601365",
"error_uri": "https://login.microsoftonline.com/error?code=90014486"
}
You should specify application/x-www-form-urlencoded as the value of the header Content-Type. Then this error will not exist.
But based on your previous post, you have set the application/x-www-form-urlencoded. So if it's not the reason for this issue, please provide more details: Where are you generating the access token? In Postman? Could you provide a screenshot?
But there is another error. You should use grant_type=authorization_code instead of grant_type='authorization_code'.
And you should provide some other parameters. See this sample: Request an access token.

Unable to register new destination using RegisterDestination in Amazon MWS API

When I try to register any new subscription destination using RegisterDestination (Amazon MWS Subscriptions API) I received error:
"An exception was thrown while attempting to Create a Destination. This can happen if the Destination has already been registered."
I try many randoms (100% unique) urls.
ListRegisteredDestination return empty list.
Thank for help
My Request:
POST /Subscriptions/2013-07-01?AWSAccessKeyId=myAccess-Key
&Action=RegisterDestination
&SellerId=My-Seller-ID
&SignatureVersion=2
&Timestamp=2017-01-27T18%3A48%3A28Z
&Version=2013-07-01
&Signature=cybKM%2BtLq4F%2Fv%2BZnGhPtyLHg%2FCiOk31WbG0tHmpGQFg%3D
&SignatureMethod=HmacSHA256
&MarketplaceId=MyMarketPlaceId
&Destination.DeliveryChannel=SQS
&Destination.AttributeList.member.1.Key=sqsQueueUrl
&Destination.AttributeList.member.1.Value=http%3A%2F%2Fsomeurl.pl%2Famazon%2Fnotlistner HTTP/1.1
Host: mws.amazonservices.de
x-amazon-user-agent: AmazonJavascriptScratchpad/1.0 (Language=Javascript)
Content-Type: text/xml

How can I disable Websphere's 8.5 default 4xx message?

I have a Jersey REST application in Websphere 8.5. Whenever my resource responds with a 4xx response, Webpshere (or IBM Http Server) overwrites the response body with its default error message, for example:
Error 404: Not Found
Not only don't I want the response body to be overwritten, I want the response body as produced by my resource, but also Websphere does not update the Content-Length: response header, thereby creating an inconsistency between content-length and the actual response body length.
Is there a way to force Websphere (or IBM HTTP server) to not overwrite the response body when my resource produces a 4xx response?
For example a call to the following resource:
#Path("timeout")
public class TimeoutService {
#GET
#Path("withbody")
#Produces(MediaType.APPLICATION_JSON)
public Response getWithBody() {
Response.ResponseBuilder builder = Response.status(Response.Status.NOT_FOUND);
builder.entity("{ \"status\" : \"notok\" }");
return builder.build();
}
}
will result in:
Error 404: No
Request Method:GET
Status Code:404 Not Found
Response Headers
$WSEP:
Connection:Keep-Alive
Content-Language:en-US
Content-Length:13
Content-Type:text/html;charset=ISO-8859-1
Date:Tue,21 Apr 2015 11:50:38 GMT>
Keep-Alive:timeout=15, max=100
X-Powered-By:Servlet/3.0
Note how the default message gets truncated because of the inconsistent content length.
But what I want is this call to respond with a 404 and { "status" : "notok" } and Content-Type set to application/json
Yes, you can. Here is the page that outlines the Jersey property that needs to be changed to disable WAS hi-jacking your errors:
https://java.net/jira/browse/JERSEY-2521
In short, you have to set the property org.glassfish.jersey.server.ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR to true when you configure Jersey.

Override Message-ID by configuration

When I send email from my application using the default WildFly mail session, the auto-generated message ID gives away that my server is WildFly:
Message-ID: <524672585.11.1429091886393.JavaMail.wildfly#myserver.example.com>
For security reasons, I'd like to suppress or override the wildfly substring in the message ID.
Is there a configuration element or a system property to do that?
Answering my own question: The wildfly part of the message ID corresponds to the value of the user.name system property. My server happens to be running under a Linux user account named wildfly.
So one option would be to use a different user account. Alternatively, simply passing -Duser.name=foo to the WildFly start script is enough to change the message ID.
Upgrade to JavaMail 1.5.3. That official release has Bug 6496 -Message-Id leaks current user/hostname of the Java process marked as resolved.
Otherwise, the Message-ID computation uses the InternetAddress.getLocalAddress method which is including the username. You can set the mail.from session property to override including the O/S user name.
public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.put("mail.from", "------#bar.baz");
Session s = Session.getInstance(props);
MimeMessage m = new MimeMessage(s);
m.addFrom(InternetAddress.parse("foo#bar.baz"));
m.setText("");
m.saveChanges();
m.writeTo(System.out);
}
Which will output something like:
From: foo#bar.baz
Message-ID: <1688376486.0.1429814480627.JavaMail.------#bar.baz>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
If you are using the default session you can just add 'mail.from' to the system properties.

Resources