Archive

Archive for the ‘Things that can drive you mad’ Category

Setting up SSL with Amazon Elastic Beanstalk

November 12, 2014 Leave a comment

Setting up a service using Amazon’s EBS is very easy.  The documentation is clear and to the point.

However, when you try to turn on SSL, you might run into problems, as the many forum questions suggest.

Most issues revolve around two main points:

1. SSL certificate.  Getting a certificate uploaded to Amazon is not as easy as it sounds, you need to install amazon’s CLI and make sure your certificates are in the right format.  Sometimes you even need to make changes (change order of entries within the certificate, remove parts, etc.).  If you use Godaddy as a certificate source, just download an Apache compatible certificate and you can upload it as is.

2. Setting up the environment.  You can find the instructions here, and they’re all good until you get to step 3.  That’s where Amazon tells you that IF you are using VPC with your instances, you need to setup rules to allow https.  What they fail to say is that even if you don’t use VPC you still need to setup rules!

The following are instructions I got from Amazon support, after struggling with this for a couple of weeks (did not have business level support when I started working on this issue):

You need to update two security groups, one for your ELB and one for your instance, both must allow https (443)

  1. Go to your ec2 web console and click on “security groups” on the left
  2. Find the group with the following description: “ELB created security group used when no security group is specified during ELB creation – modifications could impact traffic to future ELBs”
  3. Add a rule for that group to allow https protocol port 443 from source 0.0.0.0/0
  4. Find the security group for your environment in that same list, and add https port 443 with the source being the default security group from step (2)

This should allow https connectivity between your load balancer and your instance.

Advertisements

Here’s one to drive you mad: is your message not replaced correctly by ResourceBundle or Spring’s ResourceBundleMessageSource?

August 15, 2013 Leave a comment

Apparently, you can put almost anything in those i18n messages, EXCEPT for a single quote!  
If you do that, your single quote will disappear (easily missed), and all place holders after the quote will not be replaced (easily noticed).

So, for example, if you have a message like this:

That's message 1, and {1} should be replaced by the word one

you will get an output of

Thats message 1, and {1} should be replaced by the word one

instead of the expected:

That's message 1, and one should be replaced by the word one

However, if you follow the rules, and put two single quotes instead of one (notice the added quote in That’s):

That''s message 1, and {1} should be replaced by the word one

You will get the correct behavior.

Follow the rules, and all shall work out fine!

Another one of those irritating “you can’t do this but I won’t tell you why” in eclipse

November 4, 2012 Leave a comment

I decided to clone my base project (basic service) to start a new project, so I used git to fetch it to my local drive, then tried to import to my workspace using file->import->maven->existing maven projects.  Picked my new cloned project, and indeed the POM.xml file appeared, but the checkbox next to it was unclickable!  Of course eclipse won’t tell you why, so after searching the web and trial and error, I finally figured it out:

If you already have a project by the name specified in the POM, you can’t create a new one with that name from the POM.xml

In order to get through this issue, you need to add a suffix in the Advanced->Name template field (just adding “clone” was enough for me) or change it in the POM.

HTH

Eclipse quirks #1 – sometimes the project just stops doing what it should

October 17, 2012 1 comment

This happened to me today:  I added google Guava to my pom (for using their ImmutableSet collection), maven imported the jar correctly, but for some reason Eclipse refused to show it in the maven dependencies list, and the ImmutableSet import did not work (would not show me the option to add a java import statement, and adding it manually did not find the google library).

The reason for this eludes me, so can’t solve the bug, but I do know a quick work around:

  1. close Eclipse
  2. go to the project directory
  3. in terminal, enter:
    mvn eclipse:clean
  4. do NOT run mvn eclipse:eclipse as this will create an eclipse project which has a weird structure in eclipse, instead, do the following:
  5. re-run eclipse, go to file->import, select maven->existing maven project, choose your project directory, eclipse should recognize your pom, click finish, and voilla, your project will start working again.

This will probably work for any unclear state the project goes into in eclipse, not just import issues.

Spring message translation found in JSP but not in controller

September 20, 2012 1 comment

Well, this one had me searching the web for a while, for no avail.  Finally figured it out!

Here’s the problem:

You defined everything correctly to setup your web app to be i18n compatible using Spring, you even got messages to be translated when in jsp view mode, but now you want to translate a message in your controller.  Sounds simple?  not so (unless you know the secret).

So you looked in the web, and found that you need to declare the following:

@Autowired
private MessageSource messageSource;

You already have the MessageSource bean setup (for the View part) in spring-servlet.xml like so:

<bean id=”messageSource”
    class=”org.springframework.context.support.ReloadableResourceBundleMessageSource”>
    <property name=”basename” value=”/WEB-INF/i18n/messages” />
    <property name=”defaultEncoding” value=”UTF-8″/>
</bean>
 
And  still, when you try to run it through messageSource in your controller, you get NOTHING, empty string.  And if you look closely, you will find that you have a DelegatingMessageSource in your messageSource property, with an empty parent source, which means it is EMPTY, i.e. always returns blank.

Well, here’s the thing:  Spring will setup a DelegatingMessageSource when it can’t find a message source definition.  What’s that, you say?  it DID find a message source, it found it for my View!  That’s true, it did find it for the view, but not for your controller.  Why is that?  I don’t really know, but fortunately, I know how to fix it 🙂

So, here’s the solution for this little challenge: move your messageSource definition from spring-servlet.xml to applicationContext.xml!

This will let Spring find your messageSource for your Controller as well, and all will be well.

 

Using REST in cloudbees – not so simple

September 13, 2012 2 comments

Well, this one is going into “things that can drive you mad” for sure, as it took me a couple of days to reach the inevitable conclusion that I have to give up 😦

So here’s the thing:  you created a RESTful application, using the proper GET/PUT/POST/DELETE headers where appropriate, it works great on your local Jetty/Tomcat deployment, but when you try to run it on the cloud, it fails.  After much testing and debug prints, you find that when using PUT & DELETE the request gets there BUT the body embedded  parameters do not.

If this sounds familiar, you’ve got a problem.  As it is right now (Sep. 2012), app servers are not obligated to parse parameters delivered with PUT/DELETE requests if they are sent in the body (like in POST), because the standards to do not define that behavior.  Some will do it, some won’t, and there’s no one to complain to!

You can, of course, do all kinds of work arounds like setup a filter to parse the request on your own, or even do it in the methods, but I hate work arounds, they have a tendency to fail at some point when things change.

In the end, my solution to cloudbees deployment was to get rid of PUT altogether, and use DELETE only in requests which do not need anything in the body.  While this will work, I am unhappy with this solution, to the point of thinking about going to EC2 and not working with Cloudbees!  My applications should work as required, and should not depend on the hosting platform’s limitations!!

UPDATE!

Following Michael’s comment (see below), I gave this item some more attention, and finally got it to work!

As it turns out, it IS possible to use PUT and DELETE in cloudbees, you just need to know how to make it work.  Since PUT requests are not parsed like POST, there is a trick to make the application side parse it correctly.

The way I did it, is by using @RequestBody to pass the data to my dto on the server side, setting my content type to application/json;charset=UTF-8 on the jQuery side, and using JSON.stringify to set the content correctly so it can be parsed by my JSON converter.

So, my method looked like so:

@RequestMapping(value=”{id}/status/read/}”, method=RequestMethod.PUT)
public ResponseEntity<String> markRead(
@CookieValue(value=Constants.AUTHENTICATED_USER_ID_COOKIE, required=false) UUIDValidatedString userIdCookie, 
@PathVariable UUIDValidatedString id,
@RequestBody TestDto test
) {

}
 
and my ajax side looked like so:
 
function internalMarkMessageReadStatus(messageId) {
var obj = new Object();
obj.test = “true”;
$.ajax({
url: ‘/api/messages/’ + messageId + ‘/status/read/’ ,
type: ‘PUT’,
dataType: ‘json’,
contentType: “application/json;charset=UTF-8”,
data: JSON.stringify(obj),
success: function(response) { 
}
});
}
 
The DTO is just a simple POJO:
 
package com.tipabout.dto;
import org.codehaus.jackson.annotate.JsonAutoDetect;
@Document
@JsonAutoDetect()
public class TestDto {
public String test;
 
public TestDto() {
}
 
public String getTest() {
return test;
}
 
public void setTest(String test) {
this.test = test;
}
}
 

Sending objects to your server from jQuery using POST/PUT and accepting using Spring & Jackson

August 24, 2012 Leave a comment

I won’t cover the basics of how to do REST using jQuery and Spring/Jackson in this post, hopefully I’ll find the time to post a whole series about this, so for this post I’ll assume you’ve followed all the tutorials you found online (quite a few helpful ones, shouldn’t be a problem)

So now you have your app server setup, your controller setup, you’ve created a method that’s supposed to get the object, and a javascript that should send it, BUT it just doesn’t work.  I ran into this problem, here’s what I had setup:

I was already using $.ajax instead of $.getJSON so I could send PUT requests, which means I could influence all aspects of the request (getJSON doesn’t let you do that).  I was sending the following request:

$.ajax({
url: ‘/api/users/configuration/’,
type: ‘PUT’,
dataType: ‘json’,
data: {
  configuration: JSON.stringify(userConfiguration)
},
success: function(response) { 
}
});

where  userConfigurationwas an object holding key and value pairs, and looked like this after stringifying it: {“exposure”:6,”publicName”:1}

And I expected the following code to catch it and translate it correctly to an object:

@RequestMapping(value=”/configuration/”, method=RequestMethod.PUT)
public ResponseEntity<String> setConfiguration(
HttpServletRequest request,
@ModelAttribute(“configuration”) Configuration configuration, BindingResult result 
) {
//  … do something with it
}

Several things had to be fixed for this to work out:

first of all, my javascript had to change a bit, I had to add application/json to the request descriptions so that the server knows it needs to parse it as JSON, and I had to stop sending a key-value pair, I only had to send the object itself (so remove the configuration: part)

This made my js code look like this:

    $.ajax({
    url: ‘/api/users/configuration/’,
    type: ‘PUT’,
    dataType: ‘json’,
    contentType: “application/json; charset=UTF-8”,
    data: JSON.stringify(userConfiguration),
    success: function(response) { 
    }
    });

Next, my request handling needed to change:

I was using @ModelAttribute, which may be good for any number of things, BUT it isn’t good for what I was trying to do.  I had to use @RequestBody instead.  Also, I was passing a domain object called Configuration, but didn’t really need the whole object, just the items map part of it, so I ended up just sending that.

so my server side code changed to:

@RequestMapping(value=”/configuration/”, method=RequestMethod.PUT)
public ResponseEntity<String> setConfiguration(
HttpServletRequest request,
@RequestBody Map<String, Integer> items
){
// do something interesting with this input
}

This was tricky to solved, I looked at quite a few tutorials, questions, etc., but it took some messing about to get it all in place.  This post right here is what finally sorted it all out, you might want to go visit that guy’s post as well.