====== How to write a jSeduite Web Service ======
Building a Web Service using the JAx-WS framework is not such a big deal.
But, to ensure that the service can be included inside the jSeduite service pool, you **must** follow a set of guidelines and then make jSeduite maintainer's life easier (and it's not such a big deal too LOL ).
**''$JSEDUITE_HOME''** refers to the folder where you've //checkout--ed// the SVN repository content.
===== Netbeans Project Creation =====
* Create a new project inside your workspace:
* Choose the ''Java Web'' //category//, and then the ''Web Application'' //project// type.
* //Name & Location//:
* Set the ''Name'' to your service name (without the ''Service'' postfix)
* **Be sure** that you're using ''$JSEDUITE_HOME/webservices'' as ''Project Location''
* Tick the ''Use dedicated folder for storing librairies'' box
* Click ''Next''
* //Server & Settings//:
* Use the **local** GlassFish V2 as ''Server''
* Set the ''Context Path'' to ''/jSeduite/ProjectName'' instead of ''/ProjectName''
* Click ''Finish'' as we're not going to use any built-in framework.
===== Web Service Creation =====
* Right click on you project root, and then choose ''New / Web Service''
* //Name & Location//:
* Enter the service name as //Web Service Name//
* Use the following scheme to define the ''Package'': ''provider.**jSeduite.technical**.category''
* //eg// use the ''fr.unice.i3s.modalis.jSeduite.technical.image.picasa'' package to represent a service published by ''modalis.i3s.unice.fr'' which deals with ''image'' category and more precisely ''picasa'' concept.
* Click ''Finish''.
* The Java editor will open the new Web Service class file
* Insert the //[[:arch:licence|licence header]]// code before the class declaration
If you wan to save a lot of time (and make Netbeans more reactive), deactivate the ''auto-deploy'' silly mechanism:
* Right click on the Project root node, and select ''Properties''
* Choose the ''Run'' node in the left panel
* Untick the ''Deploy on save'' check box.
===== Interface Creation =====
* Switch the service into //Design// view.
* Use the //Add Operation ...// wizard to generate operations skeletons
* Really use it to generate skeletons, it saves a lot of time
* Customize the skeletons by hand to add more advanced concepts (like array, exotic objects, ...)
* After creating all operations, switch to the //Source// view
* Check operation signature definition, and fix the code //look// if Java conventions are violated
* Comment all operations using the standard javadoc tags
Here is an example of such an operation:
/** Log an error inside the system
* @param trigger Name of the orchestration where the error was catched
* @param level log level [eg SEVERE, INFO, WARNING, FATAL, ...)
* @param message the content of the error message
*/
@WebMethod(operationName = "log")
@Oneway
public void log(@WebParam(name = "trigger") String trigger,
@WebParam(name = "level") String level,
@WebParam(name = "message") String message) {
// Your code goes here ...
}
===== Business Object =====
If the web service use a complex data model, this model **must** be defined as a simple Java class as JAX-WS will manipulate simple [[wp>POJO]].
* Right click on the ''Source Packages'' node
* Choose your package name, and then right-click and choose ''New / Java Class''
* Include the [[:arch/licence|licence header]] comment
* Define the data class:
* All attributes are ''private''
* You **must** define a constructor with 0 parameters as JAX use Java intercession capabilities to build POJOs from SOAP messages at runtime.
* When an attribute got a //getter// and a //setter// it can be serialized into XML and then exchanged with the //real world//.
**Warning**: Be careful on the name you give to your business object class ...
* If an exception occurs at deployment time (//Exception occured in the wsgen process javax.xml.ws.WebServiceException: Unable to create JAXBContext//), the XML serialization process fails somewhere.
- You forgot to define a constructor with no args
- You're using a //weird// name for you class. As each Web service operation is mapped into a ComplexType, you cannot define a Class with the same name as an operation's one.
* => You cannot define a ''Log'' data class if you're defining a ''log(...)'' operation.
===== Librairies =====
==== Database connectivity ====
**Database usage MUST be handled trough the [[:services:libs:databaseconnection]] library.**
* Right click on the ''Library'' node.
* Choose ''Add Project''.
* Go to ''$JSEDUITE_HOME/librairies'' directory
* Select the ''DatabaseConnection'' project (java cup)
* Be sure that the ''dist/DatabaseConnection.jar'' file is highlighted on the right panel
* Click on the ''Add Project Jar Files'' button to create the link.
* Add the following ''import'' statement inside your service code:
import fr.unice.i3s.modalis.jSeduite.libraries.mysql.*;
==== Third Party ====
* To include //third party// libraries, right click on the //Librairies// node inside the project.
* Select the ''Add JAR/ Folder'' menu item.
* Go to you library ''jar'' file using the file chooser panel
* Tick the ''Copy to Librairies Folder'' radio button
* Validate the library using the ''Choose'' button.
===== Database Scheme =====
If the web service use the database as persistent back-end, you'll have to describe the table creation process in a SQL file.
* Open the ''$JSEDUITE_HOME/librairies/DatabaseSchemas'' project
* Create a ''New SQL File'' using ''ServiceName'' as file name inside the ''Schemas'' folder
* The ''.sql'' extension is automatically added
* The script **must** use a ''DROP TABLE IS EXISTS'' statement before describing a new relation.
* => It helps the bundle deployment process.
* If you need to add initial data set, define a ''ServiceName_init'' file inside the ''Data'' package.
===== Collaborative Environment =====
==== SVN Repository ====
* Right click on the project root node
* Choose the ''Subversion'' menu item, and then ''Commit''
* Describe your code in one or two lines
* click on the ''Commit'' button
===== Documentation =====
==== Contract Extraction ====
You'll have to add the WSDL contracts (and its XSD datamodel) into the global contracts repository.
* Location: $JSEDUITE_HOME/architecture/contracts
To perform such a job, you can use the ''add_contract.sh'' bash script :
mosser@asmodeus:~/repositories/jseduite/architecture$ ./add_contract.sh http://localhost:8080/jSeduite/PartnerKeys/PartnerKeysService
# Retrieving remote files
20:37:09 URL:http://localhost:8080/jSeduite/PartnerKeys/PartnerKeysService?wsdl [2183/2183] -> "/tmp/add_contract.sh.XXXXXX.gQE41Waa" [1]
20:37:09 URL:http://localhost:8080/jSeduite/PartnerKeys/PartnerKeysService?xsd=1 [1076/1076] -> "/tmp/add_contract.sh.XXXXXX.Z37DPqk6" [1]
# Formatting XSD file
contracts/PartnerKeysService.xsd: XML document text
# Replacing schemaLocation attribute in WSDL file
# Formating WSDL file
contracts/PartnerKeysService.wsdl: XML document text
==== Architectural Description ====
The jSeduite [[:services:arch:start]] allows formal techniques to be used over the global architecture.
Enhance the ''$JSEDUITE_HOME/architecture/description/jSeduite.pl'' description using this tools to take care of your new service.
==== Wiki Description ====
* Create a wiki page inside the '':services:ws'' namespace
* Describe your service
* You **must** use the [[:services:ws:ws-template| Web Service Description Template]]
* Edit the [[:services:ws:start|Web Services index]] page and add a link to your service
==== Official Download creation ====
* Retrieve the service ''jar'' file in the ''$JSEDUITE_HOME/webservices/ServiceName/dist'' folder
* Rename it as ''ServiceName-vX.y.war'' (X and y as for the releasing process)
* Create a ''New Download'' inside the [[http://code.google.com/p/jseduite/downloads/list|GoogleCode interface]]
* Use the following pattern as download name: ''ServiceName X.y Service''
* Add the following tags: ''Type-WebService'' & ''Since-M.n'' where M.n is the current jSeduite release
* Click on ''submit file'' to upload the War file.
===== jSeduite Admin Only =====
==== Releasing Process ====
* Right click on the project root node, and then choose ''Subversion / Copy To''
* Choose the ''Remote folder'' instead of the ''Local'' one.
* Choose the ''Repository Location'' using the following scheme:
* ''releases/X.y/webservices/ServiceName''
* ''X'' is the major version number
* ''y'' is the revision number inside this version.
* Enter a message inside the ''Copy Description'': ''Service Name X.y release''
* End by clicking on the ''Copy'' button
You cannot //re-copy// a folder into the release one. If you absolutely need to perform a new release with same version number, you'll have to delete the old one before using the following command line:
mosser@asmodeus:~/repositories/jSeduite$ svn delete https://jseduite.googlecode.com/svn/releases/X.y/webservices/ServiceName
To create a new release folder, use the usual ''svn mkdir'' command from the command line:
mosser@asmodeus:~/repositories/jSeduite$ svn mkdir --parents https://jseduite.googlecode.com/svn/releases/X.y/webservices