pristupnatocka-tutorial-v2 / csharp / pristupnatocka-tutorial-csharp / README.md
README.md
Raw

pristupnatocka CSharp tutorial

Preduvjeti

dotnet tool install --global dotnet-svcutil

Koraci potrebni za implementaciju testnog scenarija

Testni scenarij prikazuje slanje poruke na Pristupnu Točku izvršavajući xUnit test. Sam proces zapravo opisuje način na koji je nastao ovaj projekt.

1. Kreirajte solution projekt

dotnet new sln -o pristupnatocka-tutorial-charp

2. Kreirajte SOAP client projekt (class library)

dotnet new classlib -o PristupnaTockaSoapClient
# Dodaj krerani projekt u solution
dotnet sln add ./PristupnaTockaSoapClient/PristupnaTockaSoapClient.csproj
  • Preimenujte Class1.cs u ClientBuilder.cs.
  • Zamijenite kod u ClientBuilder.cs sa:
namespace PristupnaTockaSoapClient;

public class SoapClientBuilder
{

}

3. Kreirajte xUnit projekt i dodajte ga u solution

dotnet new xunit -o PristupnaTockaSoapClient.Tests
# Dodaj kreirani projekt u solution
dotnet sln add ./PristupnaTockaSoapClient.Tests/PristupnaTockaSoapClient.Tests.csproj
  • Preimenujte klasu UnitTest1.cs u SoapClientBuilderTest.cs
  • Zamijenite kod u SoapClientTests.cs sa:
using Xunit;

namespace PristupnaTockaSoapClient.Tests;

public class SoapClientTests
{
    [Fact]
    public void Truth()
    {
        Assert.True(true);
    }
}

4. Dodajte referencu na PristupnaTockaSoapClient class library projekt

dotnet add ./PristupnaTockaSoapClient.Tests/PristupnaTockaSoapClient.Tests.csproj reference ./PristupnaTockaSoapClient/PristupnaTockaSoapClient.csproj

5. Provjera postavki projekta

dotnet test

Microsoft (R) Test Execution Command Line Tool Version 17.4.0 (x64)
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: < 1 ms - PristupnaTockaSoapClient.Tests.dll (net7.0)

6. Generiranje SOAP klijenta za Pristupnu Točku (ServiceReference)

Navigirajte u direktorij PristupnaTockaSoapClient i izvršite sljedeće naredbe:

# Zamijenite jpt99901 sa vlastitim identifikatorom
dotnet-svcutil https://jpt99901.test.pristupnatocka.hr/ws
# dependency resolution naredba
dotnet restore

Struktura direktorija projekta nakon svih izvršenih naredbi:

Stablo projekta

7. Konfiguracija SOAP klijenta za komunikaciju sa Pristupnom Točkom

Prilagodite SoapClientBuilder.cs klasu na sljedeći način:

using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.ServiceModel.Security;

namespace PristupnaTockaSoapClient;

public class SoapClientBuilder
{
    public ServiceReference.BackendInterfaceClient BuildClient(String uri, String username, String password)
    {
        bool isHttps = new Uri(uri).Scheme.Equals("https");

        ServiceReference.BackendInterfaceClient client = new ServiceReference.BackendInterfaceClient(GetBasicHttpBinding(isHttps), new EndpointAddress(uri));

        client.ClientCredentials.UserName.UserName = username;
        client.ClientCredentials.UserName.Password = password;

        SetSSLAuth(client);
        SetAuthorizationHTTPHeader(client);

        return client;
    }

    private Binding GetBasicHttpBinding(bool isHttps)
    {
        BasicHttpBinding binding = new BasicHttpBinding();
        binding.Security.Mode = isHttps ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None;
        binding.Security.Transport.ClientCredentialType =
            HttpClientCredentialType.Basic;
        return binding;
    }

    private void SetAuthorizationHTTPHeader(ServiceReference.BackendInterfaceClient client)
    {
        OperationContextScope context = new OperationContextScope(client.InnerChannel);
        HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
        String usernamePassword = client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password;
        httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(usernamePassword));
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
    }

    private void SetSSLAuth(ServiceReference.BackendInterfaceClient client)
    {
        client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
        new X509ServiceCertificateAuthentication()
        {
            TrustedStoreLocation = StoreLocation.CurrentUser
        };
    }
}

Prilagodite SoapClientTests.cs klasu na sljedeći način(zamijenite jpt99901 sa svojim identifikatorom):

using System.ServiceModel;
using System.Text;
using ServiceReference;

namespace PristupnaTockaSoapClient.Tests;

public class SoapClientTests
{
    private BackendInterfaceClient backendInterfaceClient;
    private String url;
    private String from;
    private String to;
    private String password;

    public SoapClientTests()
    {
        url = Environment.GetEnvironmentVariable("PT.URL") ?? "https://jpt99901.test.pristupnatocka.hr/ws";
        from = Environment.GetEnvironmentVariable("PT.FROM");
        to = Environment.GetEnvironmentVariable("PT.TO");
        password = Environment.GetEnvironmentVariable("PT.PASSWORD");

        if (url == null || from == null || to == null || password == null)
        {
            throw new ArgumentException("Please provide all required environment variables");
        }

        SoapClientBuilder soapClientBuilder = new SoapClientBuilder();
        backendInterfaceClient = soapClientBuilder.BuildClient(this.url, this.from, this.password);

        Console.WriteLine(this.url);
    }

    [Fact]
    public void Test_SubmitMessage_With_ASICE_Payload_Call()
    {
        PartyId partyIdFrom = new PartyId();
        partyIdFrom.type = "urn:oasis:names:tc:ebcore:partyid-type:unregistered:pristupnatocka:jpt";
        partyIdFrom.Value = this.from;

        From from = new From();
        from.Role = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/initiator";
        from.PartyId = partyIdFrom;

        PartyId partyIdTo = new PartyId();
        partyIdTo.type = "urn:oasis:names:tc:ebcore:partyid-type:unregistered:pristupnatocka:jpt";
        partyIdTo.Value = this.to;

        To to = new To();
        to.Role = "http://docs.oasis-open.org/ebxml-msg/ebms/v3.0/ns/core/200704/responder";
        to.PartyId = partyIdTo;

        PartyInfo partyInfo = new PartyInfo();
        partyInfo.From = from;
        partyInfo.To = to;

        Service srv = new Service();
        srv.Value = "bdx:noprocess";
        srv.type = "tc1";

        CollaborationInfo collaborationInfo = new CollaborationInfo();
        collaborationInfo.Service = srv;
        collaborationInfo.Action = "TC1Leg1";

        Property originalSender = new Property();
        originalSender.name = "originalSender";
        originalSender.Value =
            "urn:oasis:names:tc:ebcore:partyid-type:unregistered:pristupnatocka:user:"
                + partyIdFrom.Value;

        Property finalRecipient = new Property();
        finalRecipient.name = "finalRecipient";
        finalRecipient.Value =
            "urn:oasis:names:tc:ebcore:partyid-type:unregistered:pristupnatocka:user:"
                + partyIdTo.Value;

        Property[] messageProperties = new Property[] { originalSender, finalRecipient };

        Property mimeType = new Property();
        mimeType.name = "MimeType";
        mimeType.Value = "application/vnd.etsi.asic-e+zip";

        Property[] partProperties = new Property[] { mimeType };

        PartInfo partInfo = new PartInfo();
        partInfo.href = "cid:message";
        partInfo.PartProperties = partProperties;

        PartInfo[] payloadInfo = new PartInfo[] { partInfo };

        UserMessage userMessage = new UserMessage();
        userMessage.PartyInfo = partyInfo;
        userMessage.CollaborationInfo = collaborationInfo;
        userMessage.MessageProperties = messageProperties;
        userMessage.PayloadInfo = payloadInfo;

        Messaging messaging = new Messaging();
        messaging.UserMessage = userMessage;

        LargePayloadType messagePayloadPayload = new LargePayloadType();
        messagePayloadPayload.contentType = "application/vnd.etsi.asic-e+zip";
        messagePayloadPayload.payloadId = "cid:message";

        string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        byte[] bytes = File.ReadAllBytes("./resources/asice-sample.asice");

        messagePayloadPayload.value = bytes;

        submitRequest submitRequest = new submitRequest();
        submitRequest.payload = new LargePayloadType[] { messagePayloadPayload };

        Task<submitMessageResponse> submitMessageTask = backendInterfaceClient.submitMessageAsync(messaging, submitRequest);
        submitMessageResponse submitMessageResponse = submitMessageTask.GetAwaiter().GetResult();

        Assert.NotEmpty(submitMessageResponse.submitResponse);
    }

    [Fact]
    public void Test_GetStatus_Call()
    {
        statusRequest statusRequest = new statusRequest();
        statusRequest.messageID = Guid.NewGuid().ToString();

        Task<getStatusResponse> statusRequestTask = backendInterfaceClient.getStatusAsync(statusRequest);
        getStatusResponse getStatusResponse = statusRequestTask.GetAwaiter().GetResult();

        Assert.Equal(messageStatus.NOT_FOUND, getStatusResponse.getStatusResponse1);
    }

    [Fact]
    public void Test_RetrieveMessage()
    {
        retrieveMessageRequest retrieveMessageRequest = new retrieveMessageRequest();
        retrieveMessageRequest.messageID = Guid.NewGuid().ToString();

        FaultException e = Assert.Throws<FaultException<FaultDetail>>(() => backendInterfaceClient.retrieveMessageAsync(retrieveMessageRequest)
                                                                               .GetAwaiter()
                                                                               .GetResult());
        Assert.Equal(String.Format("Message not found, id [{0}]", retrieveMessageRequest.messageID), e.Message);
    }

    [Fact]
    public void Test_GetErrorMessages_Call()
    {
        getErrorsRequest getErrorsRequest = new getErrorsRequest();
        getErrorsRequest.messageID = Guid.NewGuid().ToString();

        FaultException e = Assert.Throws<FaultException>(() => backendInterfaceClient.getMessageErrorsAsync(getErrorsRequest)
                                                                           .GetAwaiter()
                                                                           .GetResult());
        Assert.Equal(String.Format("[DOM_009]:Message [{0}] does not exist", getErrorsRequest.messageID), e.Message);
    }

    [Fact]
    public void Test_ListPendingMessages_Call()
    {
        Task<listPendingMessagesResponse> listPendingMessagesTask = backendInterfaceClient.listPendingMessagesAsync("");
        listPendingMessagesResponse listPendingMessagesResponse = listPendingMessagesTask.GetAwaiter().GetResult();

        Assert.True(listPendingMessagesResponse.listPendingMessagesResponse1.Length >= 0);
    }

}

8. Pokretanje testova

Prije pokretanja testova, kreirajte direktorij resources unutar PristupnaTockaSoapClient.Tests projekta. Unutar njega kreirajete datoteku asice-sample.asice ili iskoristite onu koja dolazi sa ovim tutorialom. Potom modificirajte PristupnaTockaSoapClient.csproj tako da dodate resources direktorij u output projekta:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
    <PackageReference Include="xunit" Version="2.4.2" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.1.2">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        <PrivateAssets>all</PrivateAssets>
    </PackageReference>
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\PristupnaTockaSoapClient\PristupnaTockaSoapClient.csproj" />
    <Content Include=".\resources\**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

</Project>

# Parametrizirano pokretanje testova
# Zamijenite jpt99901 sa svojim identifikatorom i upotrijebite dodijeljenu lozinku
dotnet test -e PT.URL="https://jpt99901.test.pristupnatocka.hr/ws" -e PT.FROM="jpt99901" -e PT.TO="jpt99901" -e PT.PASSWORD="Password123456789\!"

Poruka koja se šalje je asice-sample.asice i možete ju otvorite sa nekim alatom koji zna raditi sa .zip arhivama kao npr. 7-zip isl.

Pristupna točka i mrežna adresa

Da bi uspješno testirali slanje poruke iz vlastitog sustava možete koristiti dostupnu testnu pristupnu točku koja sadrži predefiniranog tenanta kojem možete poslati poruku.

URL - mrežna adresa PartyId
https://jpt99901.test.pristupnatocka.hr/ws jpt99901

Važno

PartyId je obavezni dio mrežne adrese pristupne točke. Iz svake mrežne adrese može se dobiti i pripadni identifikator (PartyId), tj. vlasnik mrežne adrese.