2011-03-25 35 views
22

Tengo que interactuar con un conjunto de servicios web que vienen con sus propios WSDL y XSD. Los XSD a veces se fusionan en un único archivo, a veces distribuidos a lo largo de varios archivos (20-30). Sin embargo, por experiencia sé que la mayoría de la estructura y los datos del mensaje comparten un gran subconjunto común, tal vez solo el 20% son diferentes entre las diferentes transacciones.¿Cómo fusionar partes comunes de WSDL y XSD de diferentes servicios?

Lamentablemente no tengo control sobre las partes del servidor o la declaración de los servicios, por lo que no es posible conseguir que lo arreglen. Una primera versión del cliente generó cada servicio por separado y luego los utilizó como fachadas individuales para formar un servicio coherente de nivel superior como un adaptador para otro sistema.

Utilicé CXF con el enlace JAXB predeterminado e impuse diferentes paquetes generados para cada servicio. Hice esto porque la mayoría de los servicios usan un modelo de datos común, pero no todos usan la misma versión o personalización, así que tengo conflictos y opté por la fuerza bruta para poder hacer el sistema.

Sin embargo, esto hace que los requisitos de memoria del adaptador se lleven al techo ya que cada servicio carga su contexto. En este momento tengo más de 500 millones de memoria utilizada solo para el adaptador que aloja a los clientes del servicio incluso antes de comenzar a enviar solicitudes y procesar respuestas. Aunque puedo ejecutar el sistema sin problemas utilizando la situación actual, esto crea restricciones que ponen en peligro el despliegue de la solución; a mi cliente le gustaría reducir esto drásticamente (60% o más) para que este sistema se pueda instalar junto con otros sin requerir actualizaciones de hardware.

La pregunta es la siguiente: ¿Hay alguna herramienta o técnica que me permita juntar las partes comunes de cada transacción para que se puedan generar una vez y hacer referencia a ellas cuando sea necesario?

No estoy obligado a CXF o JAXB que no sea el tiempo necesario para volver a factorizar el sistema hacia un marco diferente o enlaces de datos.

Gracias de antemano por su ayuda.

--- --- EDITAR

Gracias Blaise. Esto apunta a una característica de JAXB que sería útil: episodios. Desafortunadamente, todavía necesito extraer la base común de los diferentes servicios. Así que ahora lo que necesito es un medio para extraer estas partes comunes a través de una diff estructural, que es una herramienta diff que conocerá la estructura y la jerarquía de tipos que describe el XSD para que se establezcan referencias adecuadas para conectar las secciones comunes con las partes especializadas.

+2

Puede estar interesado en seguir esta función relacionada en EclipseLink JAXB (MOXy): https://bugs.eclipse.org/340997 –

+1

¿Están usando un espacio de nombre común para las partes compartidas? Si no, eres SOL porque las distintas partes simplemente no entienden que son lo mismo. –

+0

¿Cuánto cuesta 1 GB de memoria? ¿Cuánto cuesta tu tiempo? Señálelo al cliente. – artbristol

Respuesta

1

Si desea recortar un poco, una tecnología de clasificación alternativa (en cualquier marco) podría hacer el truco: suelte JAXB y pruebe JiBX, que se agregó a la última versión de CXF, o tal vez solo StAX.

Dado que desea hacer algo un poco más personalizado que los servicios de estilo JAX-Ws/JAXB convencionales, es posible que desee considerar Spring-WS.

Spring-WS le da control sobre todos los aspectos de la pila de servicios web.Puede enrutar mensajes de diferentes formas (carga útil, expresiones XPath, etc.) y puede usar cualquier tecnología de ordenación/serialización que desee (Jibx, jDOM, SAX, etc.)

Aquí hay una tabla que ilustra las opciones: http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#d4e1062

Si realmente quiere ser elegante, puede tomar una de las API de nivel inferior, comenzar a organizar el mensaje y una vez que llegue a la masa crítica para una de sus áreas comunes, inicie un JAXB Marshall directamente en el lugar.

La capacidad de enrutar mensajes a diferentes 'puntos finales' (en Spring-WS) significa que también puede hacer cosas como "aceptar cualquier mensaje" en esta interfaz (que se parece a DOM/SAX/etc.) y luego tener una gran operación de clasificación allí.

La clave que Spring-WS le comprará aquí es romper con el molde JAX-WS, juegue un poco al frente, y luego siempre podrá regresar a JAXB más tarde, ya sea en interceptores, su aplicación, etc. En teoría, usted puede hacer lo mismo con JAXB DOM Source, pero opino que la pila Spring-WS le brinda el mejor control para situaciones especiales como la que tiene aquí.

+0

He intentado con JiBX, XMLBeans y SDO como enlaces alternativos para JAXB. algunos ofrecieron algunos beneficios, pero todos permanecieron demasiado altos para ser prácticos. Lo mejor que podía esperar de mi prueba era una ganancia de memoria de aproximadamente un 20%, no demasiado mal pero realmente estoy apuntando al 80% + ... – Newtopian

+0

Spring-WS, sin embargo, ofrecía más, así que terminé usando Spring-WS como un marco por casi todos los motivos que usted indicó. Hasta ahora, la única solución viable que hemos evaluado es renunciar por completo al XSD y generar el XML a través de la Transformación XML. ¡La mejor respuesta hasta ahora! – Newtopian

-1

El mejor truco es servir un wsdl estático. Simplemente abra el wsdl, guárdelo, cargue en el servidor e indique al cliente que apunte al estático en lugar del auto dinámico generado.

+0

hmmm ... La generación con la que estoy teniendo problemas es la * code * generation * from * WSDL y no al revés. En realidad, el WSDL que tengo es estático proporcionado por las personas que administran el lado del servidor. Ha, y, como dije, no tengo acceso al servidor. Tal vez no fui lo suficientemente claro en la pregunta, pero estoy bastante seguro de haber cubierto todo esto. – Newtopian

Cuestiones relacionadas