невозможно отправить сообщение на конечную точку AXL - PullRequest
0 голосов
/ 25 мая 2020

Моя цель - иметь возможность публиковать и получать сообщения с конечной точки, которая использует SOAP API


структуру моего проекта

I сгенерировал клиент с файлом WSDL для целевой cucm 11.5, затем

Я последовал примеру github , создав все классы и интерфейсы, как это сделано в репозитории

в-третьих , мое решение состоит из двух проектов: библиотеки классов и проекта консоли, библиотека классов содержит созданный клиент из файла WSDL, а проект консоли состоит из класса и интерфейсов для взаимодействия с проектом библиотеки классов


У меня есть следующий класс для выполнения операции


 public class TestAxl
{

    public void CreateUsers()
    {
        var axlClient = new AxlClient(new AxlClientConfiguration
        {
            Server = "Ip to the publish server",

            User = "administrator",
            Password = "password provided"


        });




        var addUserResult = axlClient.ExecuteAsync(async client =>
       {
           var userId = Guid.NewGuid().ToString();
           var request = new AddUserReq
           {
               user = new XUser
               {
                   userid = userId,
                   userIdentity = userId,
                   password = "P@ssw0rd",
                   firstName = "test",
                   lastName = "test"
               }
           };
           var response = await client.addUserAsync(request);
           return response.addUserResponse1.@return;
       });



    }



}

, и я вызываю его из основного класса следующим образом:


 class Program
{
    static void Main(string[] args)
    {



        var letsDoSomeTesting = new TestAxl();

        try
        {
             letsDoSomeTesting.CreateUsers();



        }
        catch (Exception e)
        {



            Console.WriteLine("The following is the exceeption from calling final class ", e.Message);

        }





    }



}

когда я пытаюсь запустить консольный проект, он запускается и выходит с 0,

, затем я go возвращается в среду песочницы CUCM, и ничего не изменилось, что может быть возможная причина эта операция не работает

FYI: Runtime netCore 3.1

1 Ответ

1 голос
/ 30 мая 2020

Мне удалось собрать образец проекта, включая AXL / addUser, с Do tNet Core 3.1 на Linux: https://github.com/CiscoDevNet/axl-dotnet-samples

Это основной раздел:

// Create a custom binding so we can allow the client to use cookies with AXL
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.AllowCookies = true;

// Specify the CUCM AXL API location for the SOAP client
EndpointAddress address = new EndpointAddress( $"https://{ System.Environment.GetEnvironmentVariable( "CUCM_ADDRESS" ) }:8443/axl/" );

//Class generated from AXL WSDL
AXLPortClient client = new AXLPortClient( binding, address );

// To disable HTTPS certificate checking, uncomment the below lines
// NOT for production use!

// client.ChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
//     {
//         CertificateValidationMode = X509CertificateValidationMode.None,
//         RevocationMode = X509RevocationMode.NoCheck
//     };
// client.ChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
// client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

// Incantation to force alternate serializer reflection behaviour due to complexities in the AXL schema
// See https://github.com/dotnet/wcf/issues/2219
MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
method.Invoke( null, new object[] { 1 } ); 

// Base64 encode AXL username/password for Basic Auth
var encodedUserPass = Convert.ToBase64String( Encoding.ASCII.GetBytes( 
    System.Environment.GetEnvironmentVariable( "CUCM_USERNAME" ) + ":" +
    System.Environment.GetEnvironmentVariable( "CUCM_PASSWORD" )
) );

// Incantation to create and populate a Basic Auth HTTP header
// This must be done to force SoapCore to include the Authorization header on the first attempt
// rather than in challenge/response fashion
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
requestProperty.Headers[ "Authorization" ] = "Basic " + encodedUserPass;

// Creating context block apparently allows attaching custom HTTP headers to the request
var scope = new OperationContextScope( client.InnerChannel );
OperationContext.Current.OutgoingMessageProperties[ HttpRequestMessageProperty.Name ] = requestProperty;

//Create the request object
AddUserReq addUserReq = new AddUserReq(); 

addUserReq.user = new XUser();
addUserReq.user.lastName = "TestUser";
addUserReq.user.userid = "testUser";
addUserReq.user.password = "Cisco!1234";

string userPkid = "";

//Try the addUser request
try
    {
        addUserResponse addUserResp = await client.addUserAsync( addUserReq );
        userPkid = addUserResp.addUserResponse1.@return;
    }
catch ( Exception ex )
    {
        Console.WriteLine( $"\nError: addUser: { ex.Message }" );
        Environment.Exit( -1 );
    }

Несколько примечаний:

  • SoapCore генерирует элементы со значениями по умолчанию, когда это возможно, например nil для строковых элементов. Это вызывает проблему с <addUser>, поскольку элемент <customerName> должен быть отправлен только на HCS CUCM . Модификация AXL Soap .xsd перед запуском svcutil смогла обойти это:

    sed -i 's/name=\"customerName\" nillable=\"true\"/name=\"customerName\" nillable=\"false\"/g' schema/AXLSoap.xsd
    
  • Запросы не будут выполнены из-за проверки сертификата HTTPS самозаверяющего сертификата CUCM, если он не установлен в хранилище доверенных сертификатов CA ОС или не отключен (см. раздел с комментариями в приведенном выше коде)

  • Следующий любопытный код требовался, чтобы избежать сообщения «Компиляция сценариев JScript / CSharp является не поддерживается »ошибка при запросе (на здесь ):

    MethodInfo method = typeof( XmlSerializer ).GetMethod( "set_Mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
    method.Invoke( null, new object[] { 1 } );
    
...