How to add new services to the codon aplication (spanish)
Transcripción
How to add new services to the codon aplication (spanish)
Crear nuevos servicios para cálculos relacionados con codones. Las peculiaridades para crear servicios para codones son: Creación de servicios web BioMoby Para añadir más funcionalidad relacionada con los codones y que se puedan usar en la aplicación web de los codones , hay que desarrollar nuevos servicios web BioMoby y estar dentro de la categoría funcional (o service type) de “codons”, creada para tal efecto. Si se quiere crear un servicio web que reduzca un conjunto de datos en otro menor, se deberá registrar dentro de la subcategoría de “codons”, “Data subsets”. Para análisis de los datos obtenidos del sesgo de codones por aminoácidos se usará la categoría “analysis”. Se podrán crear nuevas categorías funcionales dentro de esta categoría si así se desea aunque se debe tener en cuenta que se puede cambiar de categoría si se considerase oportuno. Requisitos para el registro y creación de servicios web: • El tipo de servicio tiene que ser “codons” o una subcategoría de “codons”. • Si el servicio reduce el conjunto de datos de un dato a otro menor, registrarlo dentro de “Data subsets”. • Para análisis de sesgo del los codones por aminoácidos, usar la categoría “analysis”. • Dad descripciones preferentemente en inglés explicando claramente la función del servicio. • Para los tipos de los datos buscar en el repositorio de Moby aquellos que concuerden con nuestro dato, preferentemente de aquellos específicos a codones. ej. Para crear tablas de uso de codones por aminoácidos usar “CodonUsageTable_Text”, para las tablas de frecuencias de codones usar “CodonFreq_Text” con el formato siguiente: 1 Colum 2Column 3-67 colum > nameofgen [64 separated freq numbers order from AAA,AAC,AAG,AAT... to TTT, ver tabla Error: Reference source not found] ej: > >... AT1G01010 12 9 4 13 10 9 2 5 16 4 7 12 1 11 0 8 16 9 6 2 10 4 10 2 12 4 16 1 17 4 0 11 10 10 6 6 19 10 9 2 3 4 5 1 7 2 8 1 3 10 4 6 1 7 3 9 2 9 2 2 1 6 5 10 La mayoría de los tipos de datos contienen una descripción explicando su estructura y su uso. Algunas recomendaciones son mostradas en la tabla siguiente. Esto determinará los datos compatibles. Tipo de dato Tipo de dato a registrar Fichero fasta PropertySequence / FASTA Fichero GenBank GenBank_Text Tabla de freq. de codones CodonFreq_Text Tabla del uso de codones por AA CodonUsageTable_Text Código genético GenCode_Text Además del tipo de dato, existe el concepto de “formato”. El formato es la representación de un tipo de dato, de esta manera un tipo de dato puede ser representado con varios formatos, aunque un formato no tiene porqué ser compatible con todos los tipos de datos. A continuación mostramos los formatos existentes hasta el momento y los tipos de datos compatibles principales (recordar que la ser tipos de datos jerárquicos, la compatibilidad con un dato implica compatibilidad con todos los subtipos). Es posible extender compatibilidades en el futuro si se considera necesario. Formato Tipo de dato Compatibles Moby Compatible con TODOS Fasta GenericSequence GenBank GenericSequence GenBankTextPlain genBank_Text Text Plain TextPlain (FASTA,codonFreq_Text, genBank_Text...) XML Compatible con TODOS Tabla 1: Formatos disponibles y tipos de datos compatibles Si se va a realizar un servicio con un tamaño de datos de entrada o salida muy grandes (ej mayores de 5-10 MB),se recomienda hacer uso del repositorio de datos para el manejo de los datos. Si se quiere hacer uso del repositorio de datos BioData para que almacene los datos del usuario en nuestro servicio Requisitos para el registro de servicios que hagan uso del repositorio de datos BioData: • Si no existe versión del servicio sin BioData (normal), el tipo de servicio será el mismo que en el caso anterior. Si existe, añadirlo dentro de la categoría “biodata” dentro de “codons” y además poner el mismo nombre que el servicio normal acabado en “_b” sin comillas. • Todos los tipos de datos de aquellos datos que soporten el repositorio tiene que ser del tipo BioData. • Para cada tipo de dato registrado como BioData, crear un tipo secundario con el mismo nombre acabado en “_type” sin comillas, de tipo String con el valor por defecto del tipo de dato real que tendrá el dato. Por ejemplo si hacemos uso un dato genoma de tipo GenBank_Text pero registrado como BioData ya que queremos usar el repositorio, tendremos que poner su tipo real GenBank_Text como valor por defecto del parámetro secundario llamado genoma_type. • Añadir además dos campos secundarios: ◦ “exitFileName” de tipo String, que será el nombre del fichero generado, con el valor por defecto que queramos, y ◦ un campo Boolean llamado “private”, con valor false, para que el usuario decida si quiere que su dato sea privado. Illustration 1: Ejemplo de como registrar el mismo servicio dos veces, una normal, sin uso del repositorio (parte superior), y otra haciendo uso del repositorio BioData (parte inferior). Se observan las diferencias mencionadas, principalmente el los parametros secundarios, donde se tiene que añadir informacion al respecto. Tambien el nombre, acabado en "_b" y el tipo de servicio cambian. En la imagen siguiente se pueden observar las diferencias entre el registro de un servicio que haga uso del repositorio de datos con otro que no lo haga. Es especialmente importante observar los cambios en los tipos de datos, por ejemplo “sequences” es un FASTA en el servicio normal, y se convierte en BioData para usar el repositorio del mismo nombre. Se puede observar además el campo secundario con el mismo nombre del dato, “sequences_type” con el valor FASTA, para permitir conocer que tipo de dato usa el servicio. Hay muchas formas de poder realizar nuestro servicio, aquí se va a proponer un paradigma o una forma de realizarla. Consiste en dividir el proceso en dos partes diferenciadas, por un lado realizar un programa por consola en el lenguaje favorito del desarrollador y por otra la creación del servicio web BioMoby que se encarga de llamar a nuestro programa de línea de comandos: • PASO1(opcional): Creación de una clase Java que llame al programa de línea de comandos. Ver la guía con una forma de llamar a los programas por consola creados usando el lenguaje de programación Java (“1.-Crear clase para llamar programas consola”). • PASO2 : Registro y creación de un servicio web BioMoby dado un programa java. Ver guía “2.-crear servicios web BioMoby”. • PASO3(opcional): Usar el repositorio de datos BioData al llamar al programa desde el servicio (ver “3.-Crear WS consola con repositorio asincronamente”). • PASO4: Despliegue del servicio. Ver guía de servicios web BioMoby. Teniendo un programa por línea de comandos y haciendo uso de las 3 guías en el orden indicado se puede llegar a crear y registrar un servicio listo para ser usado en la aplicación web para codones. Ejemplo de creación de servicio A continuación vamos a realizar un ejemplo completo para la creación de un servicio, partiendo del programa en línea de comandos ya realizado. Para más información ver secciones sobre creación de una clase para llamar a un programa en línea de comandos y posteriormente como crear un servicio web con conexión al repositorio y creación de un servicio web BioMoby. Mostraremos el ejemplo con el servicio disponible CodonFreq. Paso1: Creación de una clase Java que llame al programa de línea de comandos: requisitos: • Tener un fichero ejecutable con el programa de línea de comandos a usar. Procedimiento: 1. Copiamos el fichero ejecutable en el servidor donde crearemos el servicio web, ya sea en la carpeta por defecto {ruta de axis en servidor tomcat u similar}/WEB-INF/conf/command o en cualquier otro sitio (necesitaremos luego la ruta completa) pero asegurándose que tenemos permisos de escritura y ejecución. 2. Solo es necesario crear una clase , que llamaremos “CodonFreq” que herede de la clase proporcionada “CommandLine”. Debemos crear un constructor que llame a la clase “CommandLine” con el nombre o ruta del fichero dependiendo de donde lo hayamos copiado. Hay 2 estrategias a seguir para generar la línea de argumentos a rellenar, en la variable cmd. La primera es crear métodos que se tendrán que llamar para introducir los parámetros, o una segunda opción más fácil de usar pero algo más tediosa de implementar, que consiste en crear constructores con los parámetros necesarios con todas las opciones posibles a gusto de cada uno. Hemos usado en este caso la segunda opción: public class CodonFreq extends CommandLine { public CodonFreq(String programPath) throws URISyntaxException { super(programPath); } public CodonFreq(String input,String output) throws URISyntaxException{ this ("CodonFreq.exe",input,output); } public CodonFreq(Reader input, String output) throws URISyntaxException, IOException{ this (iReaderToFile(input),output); } public CodonFreq(InputStream input,String output) throws URISyntaxException, IOException{ this (iStreamToFile(input),output); } public CodonFreq(String programPath,String input,String output) throws URISyntaxException{ super(programPath); if (input==null){ throw new NullPointerException("No input file given"); } if (output==null){ output = "exitCodonFreq.txt"; } cmd = new String[2]; cmd[0] = input; cmd[1] = output; //cmd contiene la linea de comandos a ejecutar } } Ya tenemos disponible la clase para llamar al programa, solo siendo necesario llamar al método callcmd() una vez creado un objeto para llamarla. Paso2: Creación de un servicio web BioMoby usando el repositorio de datos Requisitos: • Clase Java que ejecute la lógica del servicio (el programa en sí, ya sea hecho en línea de comandos o directamente en Java). Procedimiento: 1. Identificar y registrar si fuera necesario los tipos de datos (entrada “genericSequence” y salida “codonFreq_Text”), tipos de servicio (BioData dentro de codons en nuestro caso al tener un servicio sin el repositorio ya creado), nombre (usaremos repositorio, y al existir servicio normal previamente, usamos el final con “_b”) y descripción a usar por nuestro servicio. En nuestro caso registramos el tipo de dato “codonFreq_Text” que será la salida generada. 2. Registrar servicio web BioMoby en el repositorio deseado (en nuestro caso el repositorio del servidor de chirimoyo). Seguir las recomendaciones descritas anteriormente. Se observa que cada tipo que queremos que use el repositorio ha sido registrado como “BioData”, indicando luego en los parámetros secundarios el tipo real, además de campo “private” y “exitFileName”, al cual llamamos por defecto “exitCodonFreq”. Imagen 1: Registro del servicio web CodonFreq. Es un servicio que usa el repositorio de datos y está creado tal cúal se recomienda. 3. Una vez registrado, generamos el esqueleto como se describe en “Crear Servicios Web Moby” y procedemos a su implementación : 3.1. Primero vamos a usar la descripción para informar de las entradas del servicio. Para ello tenemos que crear un String con las entradas y parámetros recibidos. //componer descripcion //parametros primarios, uno por cada entrada recibida con el nombre o id si es data String params ="<fasta seq input: "+get_sequences(request).get_Id()+">"; //parametros secundarios String sec = " param-> "; sec += "<private: "+getParameter__private(request)+"> <exitFileName: "+getParameter_exitFileName(request)+">"; params +=sec; En nuestro caso tenemos una única entrada que obtenemos usando el get_sequences(request). Para los parámetros secundarios, con las funciones getParameter_nombredelparametro se obtienen igualmente. 3.2. a) Si se va a usar el repositorio de datos: Acceso normal. El servicio puede estar en cualquier máquina, aunque por motivos de eficiencia se recomienda que se encuentre en el mismo servidor que el repositorio de datos. Para ello es necesario usar 3 servicios web BioMoby, para ello se proporciona un cliente para cada uno (GetBioDataListClient, PutBioDataClient y GetBioDataClient). ej. de uso para obtener un dato: GetBioDataClient client = new GetBioDataClient(); client.setFormat(“Fasta”); client.setReturnPath(true);//true para devolver la ruta, solo local. content = client.getContent(); b) Simulando asincronismo, para lo cual el servicio tiene que estar en el servidor donde se encuentre el repositorio, es necesario usar la clase BioDataConnect, explicada en detalle en “Crear WS usando repositorio”. Esto proporciona además asincronismo en el servicio si se usa como salida un tipo BioData. En nuestro caso el servicio programa devuelve 2 ficheros de salida, uno con la frecuencia de los genes y otro con el total de los genes. Con el método del objeto BioDataConnect creado prepareOutput(nombre,descripción,formato,tipodedato,esprivado) . El nombre lo obtenemos del parámetro secundario, al igual que el tipo de dato y “esprivado”. Para el formato, usar la Tabla 1 de referencia si no se conoce cuál usar, pero hay que tener en cuenta que los programas solo aceptan un formato determinado (“genBank”, “Fasta”,etc). El método devuelve el identificador donde será guardado el dato, añadiendo dicho identificador a un conjunto de “Strings”, además de crear un objeto de salida de tipo BioData, en nuestro caso usaremos el método set_codonFreq(response,objetocreado) para devolver el identificador del dato. /*first: we create empty file before process*/ BioDataConnect output = new BioDataConnect(); String id = output.prepareOutput(getParameter_exitFileName(request) +".txt", "Codon frequencies generated by Codon Freq service: "+params, "Text Plain","CodonFreq_Text",new Boolean(getParameter__private(request)).booleanValue()); //second : devolver id Set<String> ids = new HashSet<String>();//añadir ids a un conjunto ids.add(id); BioData value = new BioData();//prepare output value.set_Id(id); set_codonFreq(response, value ); //create output object Finalmente lanzaremos la ejecución del programa de manera asíncrona, para ello es necesario crear el objeto de nuestro programa CommandLine, CodonFreq en nuestro caso, con los parámetros recibidos. Si la entrada es de tipo BioData usaremos el método setInput(id,format) de la clase BioDataConnect , nuestro objeto output, para obtener el contenido del dato asociado a dicho identificador. Puesto que el programa solo entiende de ficheros “Fasta”, tenemos que usar un formato adecuado, el llamado también “Fasta”. Una vez creado el objeto de nuestro programa, lo llamaremos usando la clase auxiliar LaunchAndCommit que se encarga de lanzar asíncronamente el programa, para ello le pasaremos además el objeto BioDataConnect output y un conjunto con los identificadores donde se generarán los datos. //third: run in a thread the program async CommandLine program = new CodonFreq(output.setInput(get_sequences(request).get_Id(),"Fasta"),output.getOu tputPath(id)); new Thread(new LunchAndCommit(program,output,ids)).start(); Creamos finalmente una hebra el programa como se muestra en la última línea. 3.3. Se recomienda controlar los errores y lanzar excepciones de tipo MobyException si la ejecución falla. @Override public void processIt(MobyJob request, MobyJob response, MobyPackage outputContext) throws MobyException { //componer descripcion //parametros primarios, uno por cada entrada recibida con el nombre o id si es data String params ="<fasta seq input: "+get_sequences(request).get_Id()+">"; //parametros secundarios String sec = " param-> "; sec += "<private: "+getParameter__private(request)+"> <exitFileName: "+getParameter_exitFileName(request)+">"; params +=sec; try{ /*first: we create empty file before process*/ BioDataConnect output = new BioDataConnect(); String id = output.prepareOutput(getParameter_exitFileName(request)+".txt", "Codon frequencies generated by Codon Freq service: "+params, "Text Plain","CodonFreq_Text",new Boolean(getParameter__private(request)).booleanValue()); //second : devolver id Set<String> ids = new HashSet<String>(); ids.add(id); BioData value = new BioData(); value.set_Id(id); set_codonFreq(response, value ); //prepare total stats file (2º exit file) try{ String outPath = output.getOutputPath(id); int index = outPath.lastIndexOf("/"); if (index==-1){ index = outPath.lastIndexOf("\\"); } outPath = outPath.substring(index+1); ids.add(output.prepareOutput(outPath+".TOT.txt", "total frequencies stats from the generated "+id+" by Codon Freq service. ", "Text Plain","CodonFreq_Text",new Boolean(getParameter__private(request)).booleanValue())); }catch (Exception e){ System.out.println("not generating total frequencies file file for : "+id); } //third: run in a thread the program async CommandLine program = new CodonFreq(output.setInput(get_sequences(request).get_Id(),"Fasta"),output.getOu tputPath(id)); new Thread(new LunchAndCommit(program,output,ids)).start(); }catch (Exception e){ throw new MobyException(e.getMessage(),e); } } Paso3: Despliegue del servicio en un servidor Apache Tomcat con Axis instalado. Imagen 2: Despliegue del servicio CodonFreq_b. Además de indicar la ruta de donde se encuentra instalado el servidor de servlets, es muy importante especificar la clase que implementa el servicio para que funcione. En nuestro caso el paquete es es.uma.ac.chirimoyo.program.service y el clase se llama CodonFreq_bImpl Siguiendo la guía de servicios web BioMoby tan solo indicamos la clase que implementa el servicio. Dependiendo de donde se encuentre el servidor y si tenemos acceso o no a el mismo, puede ser necesario contactar con el administrador para que realice el repliegue, una vez generado el archivo de despliegue. Si hubiera que copiar las clases, hacerlo en {ruta de axis en servidor tomcat u similar}/WEB-INF/classes/es/uma/ac/chirimoyo/programs/services para este servicio. Visualizadores Se pueden proporcionar además visualizadores de los distintos datos disponibles. Se proporciona uno para CodonUsageTable_Text que muestra una gráfica con el uso preferente de codones por Aminoácido. Realmente se puede desarrollar cualquier visualizador que este desarrollado para navegadores web (html+javascript) estándares, tales como Internet Explorer o Mozilla Firefox. Entre las tecnologías disponibles se pueden usar ajax (flex, zk, gwt...) con soporte de php, java, jsp, asp, ruby.... Una vez dicho esto solo será necesario permitir a nuestro visualizador cargar un fichero del tipo correspondiente para poder visualizarlo. Si se desea permitir identificadores del repositorio BioData se proporciona soporte directo para el uso del lenguaje Java (la clase BioDataConnect), además de estar disponible como servicio web BioMoby (con su clase para java también disponible), posibilitando llamar al servicio GetBioData con el identificador correspondiente para obtener el contenido del dato, incluso se puede obtener el enlace al fichero que contiene dicho dato, permitiendo trabajar de manera independiente. A continuación vamos a mostrar un ejemplo sobre como obtener un dato previamente guardado en el repositorio, con la opción de mostrar la lista de datos disponibles en el repositorio: 1. Es necesario un cliente del servicio web BioMoby “getBioDataList”.Se proporcionan un método de acceso al servicio web en java, haciendo uso de la clase GetBioDataClient, que devuelve el valor de un identificador dado. Un ejemplo de uso: GetBioDataClient client = new GetBioDataClient(bioDataId,Common.getEndpointGet()); client.setFormat("Text Plain"); client.setReturnPath(true); client.process(); path = client.getContent()); En este caso la variable path contendrá la ruta local al fichero con el dato correspondiente. Si se fuera a usar el visualizador en un servidor distinto al servidor donde se encuentran los datos, no usar setReturnPath(true), así se devolverá el contenido del fichero. Para más detalles ver “servicios web usando repositorio asíncronamente”. 2. Para obtener la lista de datos disponibles en el repositorio compatibles con el tipo de dato que vamos a visualizar, es suficiente con llamar a la dirección web donde se encuentre las interfaces y pasando como parámetro get el nombre del tipo que queremos: “listData.zul?datatype=CodonUsageTable_Text” En este caso se mostrarían solo los datos compatibles con el tipo “CondonUsageTable_Text” . Si se quisiera comunicar en listado con el visualizador para seleccionar datos, se puede hacer vía javascript. Para ello se debe implementar una función javascript,para ello el listado debe estar en un frame llamado “exfrm” dentro de la página que implementa la función javascript, llamada “loadValueFromBioData(id)” que será llamada por el listado al pulsar dos veces sobre un dato con el identificador del mismo. Activar dicha función añadiendo la variable get llamada binded con el valor “visualizador” (ej. listData.zul?datatype=CodonUsageTable_Text&binded=visualizador).