Situation : I am coding a web service in which soap client sends the request to web service which will update the database.
Suppose, there is a table project_team_members and service will be updating info of individual team member.
There is a column in table IS_TEAM_LEADER which can have '0' or '1' as value.
Problem: When updating TL info, if I am not sending IS_TL field from SOUP UI (A SOAP Client), it is automatically received as 'false' by default in java code.
How can i know if user is sending it or not, i mean i am not able to send null in case of boolean data-type from SOAP client
Revisiting my own question after so many years.
Giving response to myself at 2012 :)
One option can be, to send whatever is there in the database as it is, back to the server. But for this prior read call is necessary.
Another option is given by Jesse's(comment under question) as an answer/solution
If there is any field, e.g. Foo, there is often an associated
IsFooSpecified property to determine if the value was set or not. If
there an IsIsTeamLeadSpecified property you can access?
PS: There wasn't any field as suggested by Jesse but this can help someone else.
Related
Consider /v1/api/people/{id} endpoint handling GET, PUT and DELETE operations, where id is an integer.
I am wondering about how the below two cases should typically be handled?
a). when passed id does not exists in database, e.g. id = 100 but there is no entity of such id
b). when passed id is of wrong type e.g. it is a string "oops"
Imagine that both of above errors never actually happen as far as the real application is concerned (because e.g. application has "correct" workflow and some client-side validation).
However, I can still cause the above errors in let's say Postman or if something changes in the future, right? I want to prevent those errors in the future.
Should it be left as HTTP 500 or perhaps should it be handled as HTTP 400 or HTTP 404? Is HTTP 500 ever acceptable?
HTTP 500 - should be used as Internal Server Error meaning something unexpected happened in server side .. above errors should be part of validation ideally since they are known scenarios
a). when passed id does not exists in database, e.g. id = 100 but there is no entity of such id
here you should return 404(Not Found) with error msg like 'resource with id 100 not present for deletion/update etc' to make it user friendly
b). when passed id is of wrong type e.g. it is a string "oops"
here you should show 400 (BadRequest) since user is not passing value as per agreement that is resource id.
I am facing a strange issue:
I have a page with an email field in it when I submit the page the control goes to a servlet where I am saving the email value in session by using
request.getSession().setAttribute("email_Value", request.getParameter("email_Value"));
Now, on the basis of this email value I lookup the database and extracts the information for this user if information found then remove the session attribute by
request.getSession().removeAttribute("email_Value");
if not then redirect the request to same page with an error message and prefilled email value which I am extracting from session using
if(null!= request.getSession().getAttribute("email_Value")){
String Email = (String)(request.getSession().getAttribute("email_Value"));
request.getSession().removeAttribute("email_Value");
}
It works fine on our deleopment, UAT environments but problem is coming only on PROD where we have load balancer.
The issue is that while coming back to the same page it change the email address field witch some different email value which I have not even entered on my machine i.e. it is accessing someone else session.
Could someone provide any pointer to resolve this issue. As this is Production issue, any help would be appreciated.
Thanks
looks like you need to use sticky-sessions. This must be configured in the apache
Http is a stateless protocol meaning, the server doesnt know to identify a client over a period of time.
When a client makes a call to the server (load balanced, say server_1 & server_2), it could reach either server_1 or server_2, assume the request reaches the server_1, now your code creates a session and adds the email to the session.
When the same client makes another call to the server, this time it hits server_2, the email which is in server_1 session is not available to server_2 and server_2 might have email from another session thats why you are seeing another email address.
Hope its clear.
Solution:
URL Rewriting
Cookies
If your application is deployed on multiple servers, chances are there that your sessions may get transferred between servers. Also, in such scenarios, if you are storing any objects in sessions, they HAVE TO implement Serializable interface. If they don't, then the data will not be persisted when the session gets migrated.
Also, it seems that the session gets interchanged with another one. Are you storing anything at Application level?
I would also advice you to look into HttpSessionActivationListener for your case.
In the RabbitMQ/AMQP Java client, you can create an AMQP.BasicProperties.Builder, and use it to build() an instance of AMQP.BasicProperties. This built properties instance can then be used for all sorts of important things. There are lots of "builder"-style methods available on this builder class:
BasicProperties.Builder propsBuilder = new BasicProperties.Builder();
propsBuilder
.appId(???)
.clusterId(???)
.contentEncoding(???)
.contentType(???)
.correlationId(???)
.deliveryMode(2)
.expiration(???)
.headers(???)
.messageId(???)
.priority(???)
.replyTo(???)
.timestamp(???)
.type(???)
.userId(???);
I'm looking for what fields these builer methods help "build-up", and most importantly, what valid values exist for each field. For instance, what is a clusterId, and what are its valid values? What is type, and what are its valid values? Etc.
I have spent all morning scouring:
The Java client documentation; and
The Javadocs; and
The RabbitMQ full reference guide; and
The AMQP specification
In all these docs, I cannot find clear definitions (besides some vague explanation of what priority, contentEncoding and deliveryMode are) of what each of these fields are, and what their valid values are. Does anybody know? More importantly, does anybody know where these are even documented? Thanks in advance!
Usually I use very simple approach to memorize something. I will provide all details below, but here is a simple picture of BasicProperties field and values. I've also tried to properly highlight queue/server and application context.
If you want me to enhance it a bit - just drop a small comment. What I really want is to provide some visual key and simplify understanding.
High-level description (source 1, source 2):
Please note Clust ID has been deprecated, so I will exclude it.
Application ID - Identifier of the application that produced the message.
Context: application use
Value: Can be any string.
Content Encoding - Message content encoding
Context: application use
Value: MIME content encoding (e.g. gzip)
Content Type - Message content type
Context: application use
Value: MIME content type (e.g. application/json)
Correlation ID - Message correlated to this one, e.g. what request this message is a reply to. Applications are encouraged to use this attribute instead of putting this information into the message payload.
Context: application use
Value: any value
Delivery mode - Should the message be persisted to disk?
Context: queue implementation use
Value: non-persistent (1) or persistent (2)
Expiration - Expiration time after which the message will be deleted. The value of the expiration field describes the TTL period in milliseconds. Please see details below.
Context: queue implementation use
Headers - Arbitrary application-specific message headers.
Context: application use
Message ID - Message identifier as a string. If applications need to identify messages, it is recommended that they use this attribute instead of putting it into the message payload.
Context: application use
Value: any value
Priority - Message priority.
Context: queue implementation use
Values: 0 to 9
ReplyTo - Queue name other apps should send the response to. Commonly used to name a reply queue (or any other identifier that helps a consumer application to direct its response). Applications are encouraged to use this attribute instead of putting this information into the message payload.
Context: application use
Value: any value
Time-stamp - Timestamp of the moment when message was sent.
Context: application use
Value: Seconds since the Epoch.
Type - Message type, e.g. what type of event or command this message represents. Recommended to be used by applications instead of including this information into the message payload.
Context: application use
Value: Can be any string.
User ID - Optional user ID. Verified by RabbitMQ against the actual connection username.
Context: queue implementation use
Value: Should be authenticated user.
BTW, I've finally managed to review latest sever code (rabbitmq-server-3.1.5), there is an example in rabbit_stomp_test_util.erl:
content_type = <<"text/plain">>,
content_encoding = <<"UTF-8">>,
delivery_mode = 2,
priority = 1,
correlation_id = <<"123">>,
reply_to = <<"something">>,
expiration = <<"my-expiration">>,
message_id = <<"M123">>,
timestamp = 123456,
type = <<"freshly-squeezed">>,
user_id = <<"joe">>,
app_id = <<"joe's app">>,
headers = [{<<"str">>, longstr, <<"foo">>},
{<<"int">>, longstr, <<"123">>}]
Good to know somebody wants to know all the details. Because it is much better to use well-known message attributes when possible instead of placing information in the message body. BTW, basic message properties are far from being clear and useful. I would say it is better to use a custom one.
Good example (source)
Update - Expiration field
Important note: expiration belongs to queue context. So message might be dropped by the servers.
README says the following:
expiration is a shortstr; since RabbitMQ will expect this to be
an encoded string, we translate a ttl to the string representation
of its integer value.
Sources:
Additional source 1
Additional source 2
At time of writing:
The latest AMQP standard is AMQP 1.0 OASIS Standard.
The latest version of RabbitMQ is 3.1.5 (server and client), which claims to support AMQP 0.9.1 (pdf and XML schemas zipped).
RabbitMQ provides it's own description of the protocol as XML schema including extensions (i.e. non-standard), plus XML schema without extensions (which is identical to the schema linked via (2)) and pdf doc.
In this answer:
links in (3) are the primary source of detail
(2) pdf doc is used as secondary detail if (3) is inadequate
The source code (java client, erlang server) is used as tertiary detail if (2) is inadequate.
(1) is generally not used - the protocol and schema have been (fairly) significantly evolved for/by OASIS and should apply to future versions of RabbitMQ, but do not apply now. The two exceptions where (1) was used was for textual descriptions of contentType and contentEncoding - which is safe, because these are standard fields with good descriptions in AMQP 1.0.
The following text is paraphrased from these sources by me to make a little more concise or clear.
content-type (AMQP XML type="shortstr"; java type="String"): Optional. The RFC-2046 MIME type for the message’s application-data section (body). Can contain a charset parameter defining the character encoding used: e.g., ’text/plain; charset=“utf-8”’. Where the content type is unknown the content-type SHOULD NOT be set, allowing the recipient to determine the actual type. Where the section is known to be truly opaque binary data, the content-type SHOULD be set to application/octet-stream.
content-encoding (AMQP XML type="shortstr"; java type="String"): Optional. When present, describes additional content encodings applied to the application-data, and thus what decoding mechanisms need to be applied in order to obtain the media-type referenced by the content-type header field. Primarily used to allow a document to be compressed without losing the identity of its underlying content type. A modifier to the content-type, interpreted as per section 3.5 of RFC 2616. Valid content-encodings are registered at IANA. Implementations SHOULD NOT use the compress encoding, except as to remain compatible with messages originally sent with other protocols, e.g. HTTP or SMTP. Implementations SHOULD NOT specify multiple content-encoding values except as to be compatible with messages originally sent with other protocols, e.g. HTTP or SMTP.
headers (AMQP XML type="table"; java type="Map"): Optional. An application-specified list of header parameters and their values. These may be setup for application-only use. Additionally, it is possible to create queues with "Header Exchange Type" - when the queue is created, it is given a series of header property names to match, each with optional values to be matched, so that routing to this queue occurs via header-matching.
deliveryMode (RabbitMQ XML type="octet"; java type="Integer"): 1 (non-persistent) or 2 (persistent). Only works for queues that implement persistence. A persistent message is held securely on disk and guaranteed to be delivered
even if there is a serious network failure, server crash, overflow etc.
priority (AMQP XML type="octet"; java type="Integer"): The relative message priority (0 to 9). A high priority message is [MAY BE?? - GB] sent ahead of lower priority messages waiting in the same message queue. When messages must be discarded in order to maintain a specific service quality level the server will first discard low-priority messages. Only works for queues that implement priorities.
correlation-id (AMQP XML type="octet"; java type="String"): Optional. For application use, no formal (RabbitMQ) behaviour. A client-specific id that can be used to mark or identify messages between clients.
replyTo (AMQP XML type="shortstr"; java type="String"): Optional. For application use, no formal (RabbitMQ) behaviour but may hold the name of a private response queue, when used in request messages. The address of the node to send replies to.
expiration (AMQP XML type="shortstr"; java type="String"): Optional. RabbitMQ AMQP 0.9.1 schema from (3) states "For implementation use, no formal behaviour". The AMQP 0.9.1 schema pdf from (2) states an absolute time when this message is considered to be expired. However, both these descriptions must be ignored because this TTL link and the client/server code indicate the following is true. From the client, expiration is only be populated via custom application initialisation of BasicProperties. At the server, this is used to determine TTL from the point the message is received at the server, prior to queuing. The server selects TTL as the minimum of (1) message TTL (client BasicProperties expiration as a relative time in milliseconds) and (2) queue TTL (configured x-message-ttl in milliseconds). Format: string quoted integer representing number of milliseconds; time of expiry from message being received at server.
message-id (AMQP XML type="shortstr"; java type="String"): Optional. For application use, no formal (RabbitMQ) behaviour. If set, the message producer should set it to a globally unique value. In future (AMQP 1.0), a broker MAY discard a message as a duplicate if the value of the message-id matches that of a previously received message sent to the same node.
timestamp (AMQP XML type="timestamp"; java type="java.util.Date"): Optional. For application use, no formal (RabbitMQ) behaviour. An absolute time when this message was created.
type (AMQP XML type="shortstr"; java type="String"): Optional. For application use, no formal (RabbitMQ) behaviour. [Describes the message as being of / belonging to an application-specific "type" or "form" or "business transaction" - GB]
userId (AMQP XML type="shortstr"; java type="String"): Optional. XML Schema states "For application use, no formal (RabbitMQ) behaviour" - but I believe this has changed in the latest release (read on). If set, the client sets this value as identity of the user responsible for producing the message. From RabbitMQ: If this property is set by a publisher, its value must be equal to the name of the user used to open the connection (i.e. validation occurs to ensure it is the connected/authenticated user). If the user-id property is not set, the publisher's identity remains private.
appId (RabbitMQ XML type="shortstr"; java type="String"): Optional. For application use, no formal (RabbitMQ) behaviour. The creating application id. Can be populated by producers and read by consumers. (Looking at R-MQ server code, this is not used at all by the server, although the "webmachine-wrapper" plugin provides a script and matching templates to create a webmachine - where an admin can provide an appId to the script.)
cluster Id (RabbitMQ XML type="N/A"; java type="String"): Deprecated in AMQP 0.9.1 - i.e. not used. In previous versions, was the intra-cluster routing identifier, for use by cluster applications, which should not be used by client applications (i.e. not populated). However, this has been deprecated and removed from the current schema and is not used by R-MQ server code.
As you can see above, the vast majority of these properties do not have enumerated / constrained / recommended values because they are "application use only" and are not used by RabbitMQ. So you have an easy job. You're free to write/read values that are useful to your application - as long as they match datatype and compile :). ContentType and contentEncoding are as per standard HTTP use. DeliveryMode and priority are constrained numbers.
Note: Useful, but simple constants for AMQP.BasicProperties are available in class MessageProperties.
Cheers :)
UPDATE TO POST:
With many thanks to Renat (see comments), have looked at erlang server code in rabbit_amqqueue_process.erl and documentation at RabbitMQ TTL Extensions to AMQP. Message expiration (time-to-live) can be specified
per queue via:
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-message-ttl", 60000);
channel.queueDeclare("myqueue", false, false, false, args);
or per message via:
byte[] messageBodyBytes = "Hello, world!".getBytes();
AMQP.BasicProperties properties = new AMQP.BasicProperties();
properties.setExpiration("60000");
channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes);
Here, the ttl/expiration is in millisecs, so 60 sec in each case.
Have updated above definition of expiration to reflect this.
The AMQP spec defines a generic, extensible model for properties.
AMQP properties are somewhat similar in concept to HTTP headers, in that they represent metadata about the messages in question. Just as in HTTP, they are framed separately to the message payload. But they are basically a key/value map.
Some brokers like RabbitMQ will interpret certain message properties like expiration to add extra vendor-specific value (in that case, enforcing a TTL).
But in the end, AMQP properties are just a big bunch of key/value pairs that get safely sent along with each message, should you choose to do so. Your AMQP broker's documentation will tell you which ones they interpret specially and how to send your own ones.
All that being said, if you're asking this question in the first place then you probably don't need to worry about them at all. You will be successfully able to send messages without having to worry about setting any message properties at all.
I have a Rest API deployed on my server, say A. I have 2 web application say www.B.com and www.C.com. Both B and C calls APIs deployed on server A. Now think of small scenario,
User Rob login on B.com and user andrew login to C.com. Now some of
their event trigger to make a API call to server A. My problem is ,
any how will I able to identify that particular request coming from
B.com or C.com.
This information is only in address bar of bowser, but api call is ajax call. Necessary to mention i dont want make any change in java script or front end (on either of application B.com or C.com). Change should be on serve A.
Any hint to solve this will be highly appreciated. I am using Java, resteasy,jboss.
You can set Headers(key value pairs) in making a REST Call
Set some authentication token in the header.
Verify the token in the Server, where the REST API is exposed
Assuming you're receiving the API call from B and C as a HttpServletRequest:
String ipAddress = httpServletRequest.getRemoteAddr();
Then compare the IP address against the known IP addresses for server B and C.
If the AJAX calls come directly from the browser to A then I don't think there's a way to make this work without changing B or C.
My application is a Eclipse Rich Client and I would like to add authentication and authorization features to. My Users and roles are stored in a database and my application also has a web based admin console which lets me manage users and roles. I am leveraging Spring security on this admin console.
So here's my requirement:
I would like my thick client to provide users with a login dialog box. The authentication would need to be performed on the server side (it could be a webservice) and the roles have to flow in to the thick client. I would also like to manage sessions on the server side, somehow.
I really can't think of any easy way to doing this. I know that if I were to use Spring Rich Client, it would integrate pretty well with Spring Security on the server side.
But, that is not an option for me at this point.
Please share your thoughts on how to acheive this. Appreciate your help.
Since you're leaning toward web services (it sounds like you are) I'd think about taking the user information from your rich client (I assume user ID and password), using WS-Security to send the encrypted info to a web service, and having the web service do the auth stuff. Also I'd think about the web service returning any info that you want to go back to the rich client about the user (first/last name, etc).
I developed a similar application recently using the Challenge-Response-authentication. Basically you have three methods in your webservice or on your server
getChallenge(username) : challenge
getSession(username, response) : key
getData(username, action?) : data
getChallenge returns a value (some random value or a timestamp for instance) that the client hashes with his/hers password and sends back to getSession. The server stores the username and the challenge in a map for instance.
In getSession the server calculates the same hash and compares against the response from the client. If correct, a session key is generated, stored, and sent to the client encrypted with the users password. Now every call to getData could encrypt the data with the session key, and since the client is already validated in getSession, s/he doesn't have to "login" again.
The good thing about this is that the password is never sent in plain text, and if someone is listening, since the password is hashed with a random value, the call to getSession will be hard to fake (by replaying a call for instance). Since the key from getSession is sent encrypted with the users password, a perpetrator would have to know the password to decipher it. And last, you only have to validate a user once, since the call to getData would encipher the data with the users session key and then wouldn't have to "care" anymore.
I've a similar requirement I think. In our case:
user provides username and password at login
check this against a USER table (password not in plain text btw)
if valid, we want a session to last, say, 20 minutes; we don't want to check username and password every time the thick client does a retrieve-data or store-data (we could do that, and in fact it wouldn't be the end of the world, but it's an extra DB op that's unnecessary)
In our case we have many privileges to consider, not just a boolean "has or has not got access". What I am thinking of doing is generating a globally unique session token/key (e.g. a java.util.UUID) that the thick client retains in a local ThickClientSession object of some sort.
Every time the thick client initiates an operation, e.g. calls getLatestDataFromServer(), this session key gets passed to the server.
The app server (e.g. a Java webapp running under Tomcat) is essentially stateless, except for the record of this session key. If I log in at 10am, then the app server records the session key as being valid until 10:20am. If I request data at 10:05am, the session key validity extends to 10:25am. The various privilege levels accompanying the session are held in state as well. This could be done via a simple Map collection keyed on the UUID.
As to how to make these calls: I recommend Spring HTTP Invoker. It's great. You don't need a full blown Spring Rich Client infrastructure, it can be very readily integrated into any Java client technology; I'm using Swing to do so for example. This can be combined with SSL for security purposes.
Anyway that's roughly how I plan to tackle it. Hope this is of some use!
Perhaps this will help you out:
http://prajapatinilesh.wordpress.com/2009/01/14/manually-set-php-session-timeout-php-session/
Notice especially this (for forcing garbage collection):
ini_set(’session.gc_maxlifetime’,30);
ini_set(’session.gc_probability’,1);
ini_set(’session.gc_divisor’,1);
There is also another variable called session.cookie_lifetime which you may have to alter as well.
IIRC, there are at least 2, possibly more, variables that you have to set. I can't remember for the life of me what they were, but I do remember there was more than 1.