I am using Go for soap web service.
When I call the webservice I do like this.
request := fmt.Sprintf(para)
cli := new(http.Client)
//http.Header["http://webservice.ei"]="notify"
resp, err := cli.Post("http://127.0.0.1:8751/WebRoot/services/SecurtyWebService/notify?wsdl&targetNamespace=http://webservice.ei","text/xml;charset=utf-8",bytes.NewBufferString(request))
I get this error.
<faultstring>namespace mismatch require http://webservice.ei found none</faultstring>
I learn that the server require a targetNameSpace para. I also know that in java. People fix this by using:
QName opAddEntry = new QName("http://webservice.ei", "notify");
But I find there's no way for me to add this parameter.
Can anyone gime me some advice on how to set the namespace when calling the soap webservice in go?
Related
I have a .Net Core web API solution called ReportService, which calls another API endpoint (we can call this PayrollService) to get payroll reports. So my requirement is to mock the PayrollService using Wiremock.Net.
Also currently I have a automation test case written, which will directly call the ReportService controller and will execute all the service logic, and also classes which calls PayrollService and the DB layer logic and will get the HTTP result back from the ReportService.
Please note that the Automation test cases is a separate solution. So my requirement is to run the automation test cases like before on ReportService, and the payroll service will be mocked by Wiremock.
So, what are the changes that need to happen in the codebase? Do we have to change the url of the ReportService to be the Wiremock server base url in the ReportService solution? Please let us know, and please use the terms I have used in the question regarding the project names so I am clear.
Your assumption is indeed correct, you have make the base URL which is used by ReportService configurable.
So that for your unit / integration tests you can provide the URL on which the WireMock.Net server is running.
Example:
[Test]
public async Task ReportService_Should_Call_External_API_And_Get_Report()
{
// Arrange (start WireMock.Net server)
var server = WireMockServer.Start();
// Setup your mapping
server
.Given(Request.Create().WithPath("/foo").UsingGet())
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody(#"{ ""msg"": ""Hello world!"" }")
);
// Act (configure your ReportService to connect to the URL where WireMock.Net is running)
var reportService = new ReportService(server.Urls[0]});
var response = reportService.GetResport();
// Assert
Assert.Equal(response, ...); // Verify
}
I'm working on a project in Delphi 10.1 Berlin which integrates with GitHub. This project intends to download repositories via ZIP files. However, I'm facing some issues.
Originally, I chose (as always) to use Indy to integrate with the GitHub API. I've always used Indy for all web API consumption. However, I'm not having any success using it with GitHub.
The API requires HTTPS. I have obtained the latest OpenSSL DLLs for use with Indy, and am using the Indy library with Delphi 10.1 Berlin.
I have setup a TIdHTTP component with a TIdSSLIOHandlerSocketOpenSSL attached. I've set that IO Handler to all the Method options available, and not one gives me a valid response. I get one of two different responses...
When using sslvSSLv3, I get: error:14094410:SSL routines: SSL3_READ_BYTES:sslv3 alert handshake failure.
When using sslvTLSv1_2, I get: error:1409442E:SSL routines:SSL_READ_BYTES:tlsv1 alert protocol version
I had to resort to TRESTClient for now just to be able to work with the API. But it doesn't handle binary properly.
The test is as simple as https://api.github.com. I can call that in Chrome and Postman, and get a response. Just not via Indy.
How can I accomplish a connection with GitHub's API via Delphi's Indy library?
This Indy HTTP subclass works with the GitHub API.
type
TIndyHttpTransport = class(TIdCustomHTTP)
public
constructor Create;
end;
implementation
uses
IdSSLOpenSSL;
{ TIndyHttpTransport }
constructor TIndyHttpTransport.Create;
var
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
begin
inherited Create;
HTTPOptions := HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
SSLIO := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
SSLIO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SSLIO.SSLOptions.Mode := sslmClient;
SSLIO.SSLOptions.VerifyMode := [];
SSLIO.SSLOptions.VerifyDepth := 0;
Self.IOHandler := SSLIO;
// Request.UserAgent := 'my useragent string';
end;
Maybe your code also needs to modify the user agent string (because I use this code with different service providers, not only GitHub. Some of them require a modified user agent string instead of the default).
Source: https://github.com/michaelJustin/daraja-framework/blob/master/demo/common/IndyHttpTransport.pas
I am struggling to set-up infrastructure in my solution to send and retrieve the custom header for REST WCF Service. Basically, we need this to send UserID, password, token value from client to service and if provided values are valid then operation will continue to execute otherwise throw exception.
We already have few classes inherited from interfaces like IDispatchMessageInspector, IClientMessageInspector, IEndPointBehaviour, MessageHeader, etc., This is working fine for WCF with soap request. I tried to use these classes for my new REST WCF Service, but was not working as MessageHeader derived class supports only Soap.
I also tried using WebOperationContext, but no luck :(
Please provide a solution along with sample project to solve this problem.
Thank you so much!
Seems in your case it might be easier to interogate the ASPNET pipeline
if you add the following to your WCF service to allow it to hookup into the ASPNET pipeline
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
Then you can simply now use the HttpContext object and just get the headers as you would from a normal aspnet application, e.g
System.Web.HttpContext.Current.Request.Headers["CustomHeader"]
If you want to add http header in wcf rest service , you should use HttpRequestMessageProperty, it has a Headers property , you could set http Header through its Headers property
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
HttpRequestMessageProperty property;
// if OutgoingMessageProperties already has HttpRequestMessageProperty, use the existing one , or initialize a new one and
// set OutgoingMessageProperties's HttpRequestMessageProperty.Name key's value to the initialized HttpRequestMessageProperty so that the HttpRequestMessageProperty will work
if (OperationContext.Current.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name)){
property = OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
}
else
{
property = new HttpRequestMessageProperty();
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = property;
}
// add headers to HttpRequestMessageProperty, it will become the http header of the reuqest
property.Headers.Add(System.Net.HttpRequestHeader.Authorization, "myAuthorization");
string re = client.HelloWorld();
}
About getting the Header , just use WebOperationContext.Current.Headers.
WebOperationContext.Current.IncomingRequest.Headers["MyCustomHttpHeader"]
Please refer to http://kenneththorman.blogspot.com/2011/02/wcf-rest-client-using-custom-http.html
If I authenticate to D365 via the web browser, and then enter the following URL:
https://mytenantcode.crmserver.dynamics.com/api/data/v8.2/systemusers?$select=systemuserid,lastname,firstname,title&$top=3
I can get back the top 3 records with the data I requested.
I seem to be able to authenticate to D365 in code as per my other question (which I answered), and have an access token but I cannot seem to be able to determine how to setup the TRESTRequest object so that the Execute works.
Currently, it always returns a 401 Unauthorized error.
I've tried setting the TOAuth2Authenticator.AccessToken property to the token I received from D365, and then set the TRESTClient.Authenticator property to the TOAuth2Authenticator and the TRESTQuest.Client to the TRESTClient, which is how the examples work in the RESTDemos project, but I still get 401.
This is the last example of the code I tried, that should have worked, given that all the REST objects are linked correctly:
RESTClient.BaseURL := 'https://**mytenantcode**.**crmserver**.dynamics.com/api/data/v8.2/';
RESTRequest.Method := TRESTRequestMethod.rmGET;
RESTRequest.Resource := 'systemusers?$select={SELECT}&$top={TOP}';
RESTRequest.AddParameter('SELECT', 'systemuserid,'+
'lastname,'+
'firstname,'+
'title');
RESTRequest.AddParameter('TOP', '3');
RESTRequest.Execute;
I finally got it to return the correct information using the following code for calling the Web API:
RESTClient.BaseURL := 'https://mytenantcode.crmserver.dynamics.com/';
RESTRequest.Resource := 'api/data/v8.2/systemusers?$select=int_staffnumber,'+
'_int_serviceareaid_value,'+
'_territoryid_value,'+
'lastname,'+
'firstname,'+
'systemuserid,'+
'title';
RESTRequest.AddAuthParameter('Authorization', 'Bearer ' + AToken, TRESTRequestParameterKind.pkHTTPHEADER,
[TRESTRequestParameterOption.poDoNotEncode]);
RESTRequest.Execute;
The important change was the addition of the Authorization header parameter, and not using the Params for the query parameters as it seems the REST Client Library doesn't actually do it correctly.
Also had to change the ResourceURI for the token authorization to match the https://mytenantcode.crmserver.dynamics.com URL being used for the method call.
I'm trying to make a Spring Boot Soap WebService application, and was following the Get Started (https://spring.io/guides/gs/producing-web-service/) example to learn how to do this.
I've created what I want, but I have two URL problems with this setup and I could not find what configuration should I change to fix this :
WSDL URL basic is localhost:8080/ws/countries.wsdl but anything like localhost:8080/ws/whatever/countries.wsdl is correct
service URL for SoapUI request is localhost:8080/ws but anything like localhost:8080/ws/whatever is correct
I know that this is a feature for Spring WS, but I want a fixed URL (without 'whatever' in both cases) and could not find what to change for this
There is no straight forward way to restrict the way you want.
SOAP service is not URL based.
SOAP message body describe the endpoint.
The thing you wanted is possible following way.
Changing URL mapping in ServletRegistrationBean to restrict URL access
Existing /ws/* mapping is the reason why all the /ws/whatever url successfully responded.
Change as new ServletRegistrationBean(servlet, "/ws");
Effect will be you can not request other than /ws URL
Now the problem is, you can not get WSDL by this mapping.
Solution to get WSDL
The DefaultWsdl11Definition is actually generating WSDL from XSD on every request.
Save countries.wsdl to resource folder as static WSDL file.
Remove DefaultWsdl11Definition bean.
Create a new SimpleWsdl11Definition bean as like
#Bean(name = "countries")
public SimpleWsdl11Definition orders() {
SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
wsdl11Definition.setWsdl(new ClassPathResource("countries.wsdl"));
return wsdl11Definition;
}
Now add another static URL mapping in ServletRegistrationBean. As it will be finally look like new ServletRegistrationBean(servlet, "/ws", "/ws/countries.wsdl");
This practice is good for development phase as you can publish easily the changed definition. But it is recommended to use static-wsdl for production environment. Details ** here
Just change
return new ServletRegistrationBean(servlet, "/ws/*");
for example to
return new ServletRegistrationBean(servlet, new String[]{
"/ws/v1/countries.wsdl",
"/ws/v2/countries.wsdl"
});