Page 1 of 1

Integración con Access

PostPosted:Thu Jan 05, 2012 8:56 am
by edetron
Hola a todo el mundo

En primer lugar, felicitar a todo el equipo de desarrollo por el gran trabajo realizado.

En mi empresa estamos barajando la posibilidad de instalar un software de gestión documental. Estamos casi convencidos de que usaremos OpenKM y con la ayuda de los foros y la documentación, ya lo tenemos funcionando totalmente integrado en nuestra intranet, con Active Directory y MS SQL Server.

Ahora estamos en la fase de pruebas de integración. La mayor parte de nuestras aplicaciones están programadas con Access 2000 y para poder usar OpenKM desde ellas estamos intentando usar Web Services para comunicarlas.

Hemos instalado el Toolkit de SOAP y hemos probado a crear el código para el wsdl OKMAuth. El problema viene a la hora de llamar a cualquier función, como por ejemplo 'login'. El error que se muestra es 'Cannot find child element: user'. He usado Wireshark para comparar el mensaje que el cliente soap envía a openkm, comparando el cliente Access con un cliente java basado en Axis (desarrollado por nosostros para probar los webservices de OpenKM) que funciona correctamente:

Mensaje enviado por MS Access (que produce el error):
Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="no"?><SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAPSDK4:login xmlns:SOAPSDK4="http://endpoint.ws.openkm.com/"><SOAPSDK4:user>okmAdmin</SOAPSDK4:user><SOAPSDK4:password>admin</SOAPSDK4:password></SOAPSDK4:login></SOAP-ENV:Body></SOAP-ENV:Envelope>
Mensaje enviado por el cliente java (que funciona correctamente):
Code: Select all
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:login xmlns:ns1="http://endpoint.ws.openkm.com/"><user>okmAdmin</user><password>admin</password></ns1:login></soapenv:Body></soapenv:Envelope>
¿Alguien podría echarme una mano? He buscado por los foros y no he encontrado nada al respecto. Muchas gracias por todo.

El código fuente en Access es muy sencillo:

Clases generadas por el toolkit:

- clsof_Factory_OKMAuthServic:
Code: Select all
Option Compare Database

'*****************************************************************
'Esta clase fue creada por Web Services Toolkit de Microsoft Office 2003.
'
'Creada: 1/5/2012 09:35:57 AM
'
'Descripción:
'El Asignador de tipos genéricos es una implementación del asignador de tipos personalizado del Kit de herramientas de SOAP
'que puede asignar (serializar a XML y deshacer la serialización de XML) la mayoría de objetos COM de
'un usuario. Para obtener más información, consulte el tema Generador de objetos de la Ayuda de Web Services Toolkit de
'Microsoft Office 2003.
'
'Los cambios de código en esta clase pueden provocar un comportamiento incorrecto.
'
'*****************************************************************

Implements IGCTMObjectFactory

Private Function IGCTMObjectFactory_CreateObject(ByVal par_WSMLNode As MSXML2.IXMLDOMNode) As Object
    Dim node As IXMLDOMNode

    On Error GoTo IGCTMObjectFactoryTrap

    Set node = par_WSMLNode.Attributes.getNamedItem("targetClassName")

    Set IGCTMObjectFactory_CreateObject = Nothing

    If Not (node Is Nothing) Then
        Select Case node.nodeValue
            Case "struct_bytePair"
                Set IGCTMObjectFactory_CreateObject = New struct_bytePair
        End Select
    End If

Exit Function

IGCTMObjectFactoryTrap:
    Err.Raise Err.Number, "clsof_Factory_OKMAuthServic", Err.Description
End Function


- clsws_OKMAuthService:
Code: Select all
Option Compare Database

'*****************************************************************
'Esta clase fue creada por Web Services Toolkit de Microsoft Office 2003.
'
'Creada: 1/5/2012 09:35:57 AM
'
'Descripción:
'Esta clase es una representación de clases de Visual Basic para Aplicaciones del servicio Web
' tal y como lo define http://localhost:8080/OpenKM/OKMAuth?wsdl.
'
'Uso:
'Dimensione una variable como clsws_OKMAuthService nueva, y, a continuación, escriba código para
'utilizar los métodos proporcionados por la clase.
'Ejemplo:
' Dim ExampleVar as New clsws_OKMAuthService
' debug.print ExampleVar.wsm_getGrantedRoles("Ejemplo")
'
'Para obtener más información, consulte el tema Tipos complejos en la Ayuda de Web Services Toolkit de
'Microsoft Office 2003.
'
'Los cambios de código en esta clase pueden provocar un comportamiento incorrecto.
'
'*****************************************************************

'Dimensioning private class variables.
Private sc_OKMAuthService As SoapClient30
Private Const c_WSDL_URL As String = "http://localhost:8080/OpenKM/OKMAuth?wsdl"
Private Const c_SERVICE As String = "OKMAuthService"
Private Const c_PORT As String = "OKMAuthPort"
Private Const c_SERVICE_NAMESPACE As String = "http://endpoint.ws.openkm.com/"

Private Sub Class_Initialize()
    '*****************************************************************
    'Se llamará a esta subrutina cada vez que se creen instancias de la clase.
    'Crea sc_ComplexTypes como SoapClient30 nuevo y, a continuación,
    'inicializa sc_ComplexTypes.mssoapinit2 con el archivo WSDL encontrado en
    'http://localhost:8080/OpenKM/OKMAuth?wsdl.
    '*****************************************************************

    Dim str_WSML As String
    str_WSML = "<servicemapping>"
    str_WSML = str_WSML & "<service name='OKMAuthService'>"
    str_WSML = str_WSML & "<using PROGID='MSOSOAP.GenericCustomTypeMapper30' cachable='0' ID='GCTM'/>"
    str_WSML = str_WSML & "<types>"
    str_WSML = str_WSML & "<type name='bytePair' targetNamespace='http://endpoint.ws.openkm.com/' uses='GCTM' targetClassName='struct_bytePair'/>"
    str_WSML = str_WSML & "</types>"
    str_WSML = str_WSML & "</service>"
    str_WSML = str_WSML & "</servicemapping>"

    Set sc_OKMAuthService = New SoapClient30

    sc_OKMAuthService.MSSoapInit2 c_WSDL_URL, str_WSML, c_SERVICE, c_PORT, c_SERVICE_NAMESPACE
    'Utilice el servidor proxy definido en la configuración LAN de Internet Explorer
    'estableciendo ProxyServer en <CURRENT_USER>
    sc_OKMAuthService.ConnectorProperty("ProxyServer") = "<CURRENT_USER>"
    'Detectar automáticamente la configuración proxy si la aplicación Internet Explorer está definida para realizar esta función
    'estableciendo EnableAutoProxy en True
    sc_OKMAuthService.ConnectorProperty("EnableAutoProxy") = True

    Set sc_OKMAuthService.ClientProperty("GCTMObjectFactory") = New clsof_Factory_OKMAuthServic

End Sub

Private Sub Class_Terminate()
    '*****************************************************************
    'Se llamará a esta subrutina cada vez que se destruya la clase.
    'Establece sc_ComplexTypes a Nothing.
    '*****************************************************************

    'Intercepción de errores
    On Error GoTo Class_TerminateTrap

    Set sc_OKMAuthService = Nothing

Exit Sub

Class_TerminateTrap:
    OKMAuthServiceErrorHandler ("Class_Terminate")
End Sub

Private Sub OKMAuthServiceErrorHandler(str_Function As String)
    '*****************************************************************
    'Esta subrutina es el controlador de errores de clase. Se puede llamar desde cualquier subrutina o función de clases
    'cuando dicha subrutina o función encuentra un error. A continuación, generará el error junto con el
    'nombre de la subrutina o función que realiza la llamada.
    '*****************************************************************

    'Error SOAP
    If sc_OKMAuthService.FaultCode <> "" Then
        Err.Raise vbObjectError, str_Function, sc_OKMAuthService.FaultString
    'Error no SOAP
    Else
        Err.Raise Err.Number, str_Function, Err.Description
    End If

End Sub

................


Public Function wsm_login(ByVal str_user As String, ByVal str_password As String) As String
    '*****************************************************************
    'Se creó la función proxy desde http://localhost:8080/OpenKM/OKMAuth?wsdl.
    '*****************************************************************

    'Intercepción de errores
    On Error GoTo wsm_loginTrap

    wsm_login = sc_OKMAuthService.login(str_user, str_password)

Exit Function
wsm_loginTrap:
    OKMAuthServiceErrorHandler "wsm_login"
End Function

..................
- La llamada par hacer login:
Code: Select all
Public Sub pruebaWS()
    
    Dim authStub As clsws_OKMAuthService
    
    Set authStub = New clsws_OKMAuthService
    
    Dim user As String
    Dim pass As String
    
    user = "okmAdmin"
    pass = "admin"
    
    MsgBox authStub.wsm_login(user, pass)
    
End Sub

Re: Integración con Access

PostPosted:Thu Jan 05, 2012 4:12 pm
by pavila
Actualmente los webservices estan configurados como de tipo RPC en lugar de DOCUMENT. Mira si puede ser ese el problema. En la próxima versión 6 de OpenKM los pondremos como DOCUMENT LITERAL que parece ser que mejora la compatibilidad con clientes de terceras partes.

Esto lo puedes cambiar facilmente en las clases del paquete com.openkm.ws.endpoint y luego comoilando para volver a generar el WAR.

Re: Integración con Access

PostPosted:Thu Jan 05, 2012 4:40 pm
by jllort
para generalo tendrías que utilizar algo así:
Code: Select all
wsdl.exe http://localhost:8080/OpenKM/OKMAuth?wsdl /out:OKMAuthService.cs
Aquí tenemos algunos ejemplos de como hacer el paquete entero en C# http://wiki.openkm.com/index.php/Webservices_Guide
Puedes tambien mirar las clases que tenemos en http://openkm.svn.sourceforge.net/viewv ... KMCore/ws/

Re: Integración con Access

PostPosted:Mon Jan 09, 2012 10:55 am
by edetron
Gracias por vuestra ayuda.

En primer lugar, intenté modificar los WebService para usar el tipo LITERAL en lugar de RPC, pero en ese caso el Webservices Toolkit de Office ni siquiera generaba el código fuente.

Al final lo he solucionado de una manera algo rebuscada: He creado una dll desde Visual Basic 2005 que contiene el código para acceder a los WebServices de OpenKM (desde .NET no hay ningún problema). La única salvedad es que hay que modificar todas las clases que genera el asistente para que sean accesibles desde COM para que luego puedan usarse en VB6.

Saludos.

Re: Integración con Access

PostPosted:Mon Jan 09, 2012 6:26 pm
by pavila
Con el cambio de RPC a DOCUMENT en las versiones futuras de OpenKM mejorará la compatibilidad con los clientes de Microsoft.