Rechercher dans ce blog

Affichage des articles dont le libellé est Google app engine. Afficher tous les articles
Affichage des articles dont le libellé est Google app engine. Afficher tous les articles

mercredi 2 mai 2012

16. Google app engine

Now that we have a platform web service working, we will make the back-end in order to return and store the yoctopuce output in the database. this part does not follow the traditional design patterns but instead show a PoC.

What is Google app engine? Google app engine is a framework provided by ... (you can guess!).

"Google App Engine lets you run web applications on Google's infrastructure. App Engine applications are easy to build, easy to maintain, and easy to scale as your traffic and data storage needs grow. With App Engine, there are no servers to maintain: You just upload your application, and it's ready to serve your users."

Google App engine configuration


To set google app engine (GAE) with Intellij Idea, the facet must be enabled during the project creation. It will create a default project structure with a particular file called appengine-web.xml. In particular the file will contain:

 
16    
17   <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> 
18       <application>yocto-meteo</application> 
19       <version>3</version> 
20       <static-files>

In this configuration file, the application and the version are used by the google infrastructure to determine the current version and application.

In order to use the database, we must describe how the database is accessed. This is described in META-INF/jdoconfig.xml.
 
13    
14   <jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig" 
15              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
16              xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig"> 
17    
18       <persistence-manager-factory name="transactions-optional"> 
19           <property name="javax.jdo.PersistenceManagerFactoryClass" 
20                     value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/> 
21           <property name="javax.jdo.option.ConnectionURL" value="appengine"/> 
22           <property name="javax.jdo.option.NontransactionalRead" value="true"/> 
23           <property name="javax.jdo.option.NontransactionalWrite" value="true"/> 
24           <property name="javax.jdo.option.RetainValues" value="true"/> 
25           <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/> 
26       </persistence-manager-factory> 
27   </jdoconfig> 
28   

As soon as the Google app engine SDK is specified in Intellij Idea, you can run and debug your application using the standard UI.

Create the communication layer

For the communication layer, we would like to store the output of the YoctoHub and its localization in the database. For this purpose, Google provides a lot of help. The first step is to create an interface that specifies the functions that the server will support:


 
31    
32   @RemoteServiceRelativePath("worldmap") 
33   public interface WorldMapService extends RemoteService { 
34    
35       public void addMeteo(DataMeteo dataMeteo); 
36    
37       public List<DataMeteo> listMeteos(); 
38    
39       public void addHub(DataHub dataHub); 
40    
41       public List<DataHub> listHubs(); 
42    
43       public List<DataColor> listColors(); 
44    
45       public void addColor(DataColor color); 
46   } 
47   

This interface describes functions to list objects from database and add objects in the database. The annotation will help GAE to understand which URL must be managed by this service.

It is very important to understand that this interface (created on the client side) is used by the server. The interface used by the client will use asynchronous functions. Fortunately Intellij Idea creates such functions automatically, here is the interface that is created automatically:
 
24    
25   public interface WorldMapServiceAsync { 
26    
27       void addMeteo(DataMeteo dataMeteo, AsyncCallback<Void> async); 
28    
29       void listMeteos(AsyncCallback<List<DataMeteo>> async); 
30    
31       void listHubs(AsyncCallback<List<DataHub>> async); 
32    
33       void addHub(DataHub dataHub, AsyncCallback<Void> async); 
34    
35       void listColors(AsyncCallback<List<DataColor>> async); 
36    
37       void addColor(DataColor color, AsyncCallback<Void> async); 
38   }

On the client side, the code to call the service is the following:

private final WorldMapServiceAsync worldMapService = GWT.create(WorldMapService.class);

This will automatically create a AsyncService class that can be used out of the box.

On the server side, we implement the WorldMapService:

 
39    
40   public class WorldMapServiceImpl extends RemoteServiceServlet implements WorldMapService { 
41    
42    
43       private final Logger logger = Logger.getLogger(this.getClass().getName()); 
44    
45       private static final PersistenceManagerFactory PMF = 
46               JDOHelper.getPersistenceManagerFactory("transactions-optional"); 
47       private DAO<DataMeteo> meteoDAO; 
48       private DAO<DataHub> hubDAO; 
49       private DAO<DataColor> colorDAO; 
50    
51    
52       public WorldMapServiceImpl() { 
53           meteoDAO = new DAO<DataMeteo>(); 
54           hubDAO = new DAO<DataHub>(); 
55           colorDAO = new DAO<DataColor>(); 
56       } 
57    
58       // 
59       public void addMeteo(DataMeteo dataMeteo) { 
60           logger.info("Adding a new meteo in the Database"); 
61           meteoDAO.add(dataMeteo); 
62       } 
63    
64       public List<DataMeteo> listMeteos() { 
65           logger.info("Listing all the meteos"); 
66           return meteoDAO.list(DataMeteo.class); 
67       } 
68    
69       // 
70       private class DAO<T> { 
71           public List<T> list(Class clazz) { 
72               PersistenceManager pm = getPersistenceManager(); 
73               List<T> list; 
74               try { 
75                   Query q = pm.newQuery(clazz); 
76                   list = (List<T>) q.execute(); 
77    
78                   List<T> result = new ArrayList<T>(); 
79                   for (T dto : list) 
80                       result.add(dto); 
81                   logger.info("Server has fetched: " + result.size()); 
82                   return result; 
83               } finally { 
84                   pm.close(); 
85               } 
86           } 
87    
88           public void add(T dto) { 
89               PersistenceManager pm = getPersistenceManager(); 
90               try { 
91                   pm.makePersistent(dto); 
92               } finally { 
93                   pm.close(); 
94               } 
95           } 
96       }


What do we do here:
  • At line 45: we create the persistence manager with ID: "transactions-optional"
  • At line 59: the addMeteo function will call the DAO (declared at line 70) in order to save the add the object
  • At line 78: please note that we have to copy the objects in another list to avoid a JDO exception. 

That's all for the code! Everything is now ready to put the project in the google app engine infrastructure.

Upload your google app engine

Now that everything is working: Jenkins is successfully working and you have verified the web service is working, we can upload the application on the google infrastructure:

  1. Go in Tools->Upload App Engine Application

And that's all!!!

Warning: Do not store the GAE password in Intellij Idea and the Intellij Idea configuration file on GIT: it would mean your password (encrypted) will be stored in GIT.

jeudi 12 avril 2012

1. Introduction

When I look for projects, I usually found some code samples on a particular technology but it is quite rare to find:
  • How to install the test framework
  • How to put the project in production
  • How to use the VCS
The goal of this blog is to introduce a small project and explain the different steps of development. I will not go in details and will only provide a small overview of the project.

Overview

The goal of the project is to provide a map where you can see all the yoctopuce devices from the people who have come on the page. Yoctopuce provide a meteo sensor device that can be plugged through USB. In this project, we would like to have the following flow:


  1. An user goes on the web page with his browser
  2. The web page is loaded and tries to contact known yoctopuce device URL: http://127.0.0.1:4444
  3. If it is successful
    1. The Web page analyzes which yoctopuce devices are plugged
    2. The Web page stores the data in the database with the current location
  4. The webpage loads and displays the world map with all the yoctopuce devices stored in the database




In this blog, I will describe:
  1. Prepare GIT to store the source code
  2. Configure the maven project
  3. Configure and install a virtual appliance with Jenkins
  4. Run a code coverage with Cobertura in Jenkins
  5. Use yoctopuce devices
  6. Basic introduction of java API for yoctopuce
  7. GWT introduction
  8. Put in production with google app engine