Use Twirl in your next project

The Twirl project is the engine used by Play to support the creation of views in our projects. A some time ago, this project was separated from the core of the framework and, nowadays, is possible to use this fantastic template engine in any Scala/Java project.

The only problem is that you have to use SBT in order to have your views being compiled all the time. Thinking about that, @csokol and I have created a new project that allows you to use Twirl in every app, using SBT or not. Basically we created a class which compiles your views and other class that watches every change in the views directory.

If you are using maven, you can use whatever you want, you just need to follow a simple steps. First you have to download our project, for while you need to clone the repo and install locally. After that, you just need to run our class :).

 mvn exec:java -Dexec.mainClass="br.com.caelum.vraptor.twirl.Compiler" -  Dexec.cleanupDaemonThreads=false

Put some views in the source folder src/main/twirl/simple.scala.html, for example:

  @(customer: String)

  <html>
   <h1>Welcome @customer</h1>
  </html>

Let’s say you are writing a servlet and want to return some html for the browser. We just need to use the generated class!

   public class TwirlServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		Html clientPage = html.simple.apply("client");

		resp.getWriter().print(clientPage.body());
		resp.getWriter().close();
	}
   }

Twirl is a powerful template engine and deserves some attention. The Java world needs a new approach to write views, JSP is too old and does not have a good support to a lot of things needed by our views. You already have Freemarker but, at least in my opinion, Twirl and its compiled views is the next step. For example, you can test your view in a simple way, just invoke a method :).

   @Test
   public void shouldContainsCustomerName(){
      Html clientPage = html.simple.apply("client");
      assertTrue(clientPage.contains("client"));
   }

That is it! This was a different post, not completely related with Play, I hope you had enjoyed.

Posted in Uncategorized | Leave a comment

Reminders about deploying Play apps in Heroku

Put your application in production, also known as deploy, is one of the most important aspects of our lives as developers. This is one more thing that is too much easy with Play. Let’s walk through for some important details about deploying apps in Heroku.

There is step by step guide here. The main problem that I usually see with people that are trying to use heroku is about the details in the procfile and the database configuration. The procfile is used to configure heroku in order to start your application. This file is needed by Foreman, a ruby gem used to manage all processes necessary to run your application. Here an example:

  web: target/universal/stage/bin/acasaesuadecor-landing 
   -Dhttp.port=${PORT} 
  -Dconfig.resource=production.conf 
  -DapplyEvolutions.default=true 
  -Ddb.default.url=${DATABASE_URL}

Heroku uses the stage command to generate the deploy structure for the Play app, that is why you used this path. You need to have this file in order to run your app. It also needs to be placed in the root of your project. All information between curly braces will be provided by Heroku, in their environment.

If you take a closer look, you will see the parameter named Ddb.default.url and this is a point of confusion between a lot of people. All the information needed to connect to the database is provided in the url. You only need to configure, in your production.conf, the driver information.

 db.default.driver=org.postgresql.Driver
 #db.default.url="..."
 #db.default.user=...
 #db.default.password="..."

If you configure, for example, the password. This information will be used and you will get an exception in Heroku, explaining that the password is wrong.

That is it :). I am gonna try to write about the webjars in the next post!

Posted in Uncategorized | Leave a comment

Custom querystring parameters in Play

Usually, actions in Play does not receive complex parameters. If you take a look in your project, probably you will see just simple parameters. Integers, Longs etc. Yesterday, trying to find questions to answer in the Play forum, I found one about receiving a java.util.Date parameter in the controller’s action.

    public static Result findByDate(Date date){
    	System.out.println(date);
    	return ok();
    }

When you configure this action in your routes file, an error will be printed in your console.

    No QueryString binder found for type java.util.Date. Try to implement an implicit     QueryStringBindable for this type

By default, Play does not know how to transform a querystring parameter into a Date object. That’s why we have the QueryStringBindable interface. This is like a formatter, but to querystring parameters. The first thing we need to do is to implement our converter.

	public class DateParameter implements QueryStringBindable<DateParameter>{

		private SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		private Date value;

		@Override
		public Option<DateParameter> bind(String key,
				Map<String, String[]> parameters) {
			if(parameters.containsKey(key)){
				String date = parameters.get(key)[0];
				try {
					this.value = formatter.parse(date);
				} catch (ParseException e) {
					throw new IllegalArgumentException(e);
				}
				return Option.<DateParameter>Some(this);
			}
			return Option.<DateParameter>None();
		}

		public Date getValue() {
			return value;
		}

		@Override
		public String javascriptUnbind() {			
			return null;
		}

		@Override
		public String unbind(String key) {
			return "key="+formatter.format(value);
		}

	}

Now you need to receive this object as a parameter in your action and change your routes file as well.

    public static Result findByDate(DateParameter date){
    	System.out.println(date.getValue());
    	return ok();
    }

 GET /findByDate	controllers.NewsController.findByDate(date:binders.DateParameter)

A last thing here. In our action, we invoke the getValue method to recover the parsed date. This is why you should keep state in your QueryStringBindable object. Every time a request is made to a method receiving a DateParameter, Play will instantiate this object.

If you have or had this necessity, you can use this interface or the PathBindable, for the cases when the parameter is mixed in the url.

Posted in java, scala, jvm, playframework | Tagged , , , | Leave a comment

Customizing messages and evolutions in Play, beyond the documentation

Play has a very good forum. Every day a lot of doubts are posted and answered. As a developer who is using Play in almost every project, I follow the forum and I try to help answering as many as questions as I can. Today I bring to the blog two interesting questions that were posted there.

The first question was about how to customize the conversion error in Play. For example, if you have a int field in your class and the user submits a string, for instance, “two”, Play will use a formatter which is responsible for this conversion. If the value is not possible to be converted, a message will be returned. The default message is “Invalid value”.  In order to customize this message you have to override a key defined in Play.

    error.invalid.java.lang.Integer = Value is not a integer

But how to find this key? That is the good part!. It is not explained in the documentation and because of the question, I went to the source code and I found the file messages.default which has all pre defined errors keys in Play.

The second question was about how to run evolutions outside of the web application scope. This one was quite interesting, because I already had this wish and I was not capable to find the solution. Reading the forum, I saw a question about this subject and someone answered with the class OfflineEvolutions. So I gave a try and the code worked like a charm!

   object RunMigrations extends App{

      OfflineEvolutions.applyScript(new File("."),this.getClass().getClassLoader(), "default")
   }

Now, in case you have this necessity, you can run your evolutions in a separated task in sbt, for example. Another case is to run the evolutions every time you need to run a integration test. Again, this is not a case explained in the documentation, but based in a question posted in the forum, I had to find a answer and learned a little more.

Once more, thanks for reading!

 

Posted in java, jvm, playframework, scala | Leave a comment

Customizing the loading of provider’s configuration in Secure Social

In my last project, which I had to use a lot of features of Secure Social, I had to customize the way this plugin loads social credentials from the securesocial.conf file. Let me explain a little bit my problem. It is a multi tenant app and the tenant is defined by a subdomain. For example, client1.domain.com.br(negrito) and client2.domain.com.br(negrito) should load different configurations of facebook.

The problem is that Secure Social loads the social credentials from a configuration file. By default it is not possible to load multiple configurations, at least as far as I know :). So, in order to allow this kind of behavior, I had to specialize the provider and change this part of the plugin. Let’s see the code and the problems.

The first thing we need to is to inherit from the FacebookProvider class(italico) and override a method which name is settings(negrito)

    public class CustomFacebookProvider extends FacebookProvider{
	
    	public CustomFacebookProvider(Application application) {
    		super(application);
    	}
	
	
    	@Override
    	public OAuth2Settings settings() {
            
    	}
	
    }

This method is invoked to load the configuration. The default behavior is to load all information in the application startup, take a look in github(link para o github). Now we need to access the database and load the specific credentials of a tenant


	@Override
	public OAuth2Settings settings() {		;
		User client = Users.findByDomain(Context.current()._requestHeader().domain())
		return new OAuth2Settings(
						"https://graph.facebook.com/oauth/authorize",
						"https://graph.facebook.com/oauth/access_token",
						client.getFacebookConfig().getClientId(),
						client.getFacebookConfig().getClientSecret(),
						Option.apply("email"));
	}

There is just one problem, and it is a big one. I am using the Java version of Play and, at this point, the request was not set in the ThreadLocal(italico) used by Play to handle the execution of a client. In order to solve this problem, I had to use a little bit of bad practice of code, which is called POG here in Brazil(Programação orientada a gambiarra) . There is a method called doAuth(italico) which is responsible for authenticate a user in Secure Social and this same method receives a request as a parameter. So take a look in my solution:


        private static ThreadLocal<String> domainContext = new ThreadLocal<>();

	@Override
	public OAuth2Settings settings() {		;
		User client = Users.findByDomain(domainContext.get())
		return new OAuth2Settings(
						"https://graph.facebook.com/oauth/authorize",
						"https://graph.facebook.com/oauth/access_token",
						client.getFacebookConfig().getClientId(),
						client.getFacebookConfig().getClientSecret(),
						Option.apply("email"));
	}

	@Override
	public <A> Either<Result, SocialUser> doAuth(final Request<A> request) {
		domainContext.set(request.domain());
		Either<Result, SocialUser> doAuth = super.doAuth(request);
		domainContext.set(null);
		return doAuth;
	}

I used a ThreadLocal to store the current request and use it in the method settings(italico). I know it is not the best, but I could not store this request in a instance variable because the provider is loaded as a plugin, and plugins are singletons. Using this technique I can retrieve the domain and pass it to the method responsible for loading the tenant information.

The last part is that you have to change the configuration in your play.plugins(negrito) file.

   10001:security.securesocial.CustomFacebookProvider

That is it folks! Every week I try to write something that was useful for me in one my projects. If you have any topic that is interesting for you, comment here and I will be glad in writing about!

 

Posted in Uncategorized | Leave a comment

Plugins as extension points for your apps!

Normally, we use plugins to help us in a daily tasks, for example: send emails, secure our actions, upload files to amazon etc.  Play itself has a lot of parts built on top of plugins, more examples: evolutions, ebean and web service client. Another usage of plugins is as extension points of our apps.

In one of my current projects, the application needs to process a lot of data and provide a visualization for the client. This is a multi tenant app. So there is a core which is responsible for processing the information and there are specialized apps which are responsible for build its own visualization. Let’s take a look in the piece of code in the core:

    public class AllocationResult {

    	public String getBrokenConstraintsAsString(){
           //need the Html object with the visualization
           return html;
    	}

    }

As you can see, after processing we need to generate the visualization part. Here is where the plugin can be used.

        public abstract class BrokenConstraintsViewPlugin implements Plugin{

        	private Application application;

        	public BrokenConstraintsViewPlugin(Application application) {
        		this.application = application;
        	}

        	public abstract Html getView(Collection<ConstraintMatchTotal> constraints);

        	@Override
        	public boolean enabled() {
        		return true;
        	}

        	@Override
        	public void onStart() {
        		// TODO Auto-generated method stub

        	}

        	@Override
        	public void onStop() {
        		// TODO Auto-generated method stub

        	}
        }    }

We created the plugin as an abstract class, in order to force the client apps to inherit this class and build the visualization. Now we can use Play to load the specialized plugin!

    public class AllocationResult {

    	private static BrokenConstraintsViewPlugin constraintsPlugin = Play
    			.application().plugin(BrokenConstraintsViewPlugin.class);

    	public String getBrokenConstraintsAsString(){
    		Html html = constraintsPlugin.getView(constraints);
    		return html.body();
    	}

    }

We can pass the abstract class as argument and the Application(negrito) class will load the specialization. Of course, you need to register your plugin in the play.plugins file.

This feature is very important in order to provide extension points in your apps.  If you are building an API using Play, maybe this feature will be helpful for you :). Thanks for reading!

Posted in Uncategorized | Leave a comment

Changing the registration process in SecureSocial

This is a quick post about a customization that I had to write for a use case with Secure Social. Secure Social, at least in its 2.1.x version, has a very fixed flow in order to register a new user. First you need to register a new email, after that, an email is sent to the user with a generated token embedded in a link. The user has to follow this link in order to finish the registration process, filling the form with a few fields.

At one of my current projects, I don’t have the necessity to send the email with the generated token, the only need is to redirect the user to the registration form. To accomplish this task, we have to create a controller with a custom handleStartSignup. Basically, we need to copy the method from the Registration controller of Secure Social and delete the line which sends the email.

    import _root_.java.util.UUID
    import play.api.mvc.{RequestHeader, Result, Action, Controller}
    import play.api.data._
    import play.api.data.Forms._
    import play.api.data.validation.Constraints._
    import play.api.Play
    import securesocial.core.providers.UsernamePasswordProvider
    import securesocial.core._
    import com.typesafe.plugin._
    import Play.current
    import securesocial.core.providers.utils._
    import org.joda.time.DateTime
    import play.api.i18n.Messages
    import securesocial.core.providers.Token
    import scala.Some
    import securesocial.core.IdentityId
    import scala.language.reflectiveCalls
    import securesocial.controllers.Registration

    object CustomRegistration extends Controller {

      def handleStartSignUp = Action { implicit request =>
        if (Registration.registrationEnabled) {
          Registration.startForm.bindFromRequest.fold(
            implicit errors => {
              BadRequest(use[securesocial.controllers.TemplatesPlugin].getStartSignUpPage)
            },
            email => {
              // check if there is already an account for this email address
              UserService.findByEmailAndProvider(email, UsernamePasswordProvider.UsernamePassword) match {
                case Some(user) => {
                  // user signed up already, send an email offering to login/recover password
                  Mailer.sendAlreadyRegisteredEmail(user)
                  Redirect(Registration.onHandleStartSignUpGoTo).flashing(Registration.Success -> Messages(Registration.ThankYouCheckEmail), Registration.Email -> email)
                }
                case None => {
                  val token = createToken(email, isSignUp = true)
                  //original line
                  //Mailer.sendSignUpEmail(email, token._1)
                  Redirect(s"/signup/${token._1}")
                }
              }
            })
        } else NotFound(views.html.defaultpages.notFound.render(request, None))
      }

      private def createToken(email: String, isSignUp: Boolean): (String, Token) = {
        val uuid = UUID.randomUUID().toString
        val now = DateTime.now

        val token = Token(
          uuid, email,
          now,
          now.plusMinutes(Registration.TokenDuration),
          isSignUp = isSignUp)
        UserService.save(token)
        (uuid, token)
      }

    }

The better approach would be to write a custom plugin which could handle these steps of the registration process, but Secure Social does not provide this customization. Now, you need to change your file of routes to use the new method.

   //rest of your file
   POST  /signup br.com.celerate.security.CustomRegistration.handleStartSignUp

If you try this code, you will notice that was generated a new problem in your project. The default startSignupView page of SecureSocial uses the old method Registration.handleStartSignUp, we need to customize this view as well. It is not hard, just follow the steps described in the original site. You have to implement all methods from the TemplatesPlugin trait, but we only need to customize the startSignUp,  so let’s keep the others. In order to make this job easier, use as an example the DefaultTemplatesPlugin class.  To do not create the view from scratch, just copy the code from the original, again.

As you can see, it was little bit hard to customize this behavior. Remember that you always can use the source code of the lib as a path to discover something. Of course, it’s easier to start for the documentation and forums but, if you don’t find, don’t stop and try to take a look in the source code. Secure Social has a code that is not hard to understand. See you!.

Posted in java, jvm, playframework, scala | Tagged , , | Leave a comment