Okey so after searching for 3 hours and trying various options, I no longer have any clue how to solve this...
The situation:
Our nationwide packet deliverer (Die Post) offers a webservice for checking if an address exists.
I contacted them, received username and password for the application as well as the .wsdl-file.
I made a service reference to the downloaded file and can use the classes without problems.
Now the problem:
We have 2 other webservices which the previous programer set up with authentication and everything, I just copy pasted the code from one of the services and set everything to current one, but when I try to get a response, I always get an error (Internal Error), with no more information.
I found a way to get the last request and the only difference from the request to the one in the SoapUI (which works perfectly fine) is that, instead of "<soapenv:Header/>" it is
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://post.ch/AdressCheckerExtern/V4-01-00</Action>
</s:Header>
The current code is:
// Create Request
PostAdressChecker.AdressCheckerRequestType adrRequest = new PostAdressChecker.AdressCheckerRequestType()
{
Street = strStrasse,
HouseNbr = strHausnummer,
Zip = strPlz,
Town = strOrt,
Params = new PostAdressChecker.AdressCheckerRequestTypeParams()
{
CallUser = "TU_99660_0001",
SearchLanguage = "1",
MaxRows = "10",
SearchType = "10"
}
};
BasicHttpBinding basicBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)
{
ReaderQuotas = { MaxStringContentLength = int.MaxValue },
MaxReceivedMessageSize = int.MaxValue,
SendTimeout = new TimeSpan(0, 2, 0)
};
PostAdressChecker.ACHePortTypeClient client;
client = new PostAdressChecker.ACHePortTypeClient(basicBinding, new EndpointAddress(strUrl));
client.Endpoint.Behaviors.Add(new PostSigningEndpointBehavior(strUsername, strPassword));
SoapTracer RequestInterceptor = new SoapTracer();
client.Endpoint.Behaviors.Add(RequestInterceptor);
try
{
PostAdressChecker.AdressCheckerResponseType adrResponse = client.AdrCheckerExterne(adrRequest);
}
catch (Exception ex)
{
strError = ex.ToString();
}
Does anybody have an idea how to debug/solve this?
Thank you very much and best regards
in perl I do it like this. maybe this can give you some inspiration ...
sub clientFactory {
my $wsdl = XML::Compile::WSDL11->new('etc/adrCheckerExterne-V4-01-00.wsdl');
$wsdl->importDefinitions('etc/adrCheckerExterne-V4-01-00.xsd');
$wsdl->importDefinitions('etc/adrCheckerTypes-V4-01-00.xsd');
my $basic_auth = sub {
my ($request, $trace) = #_;
my $authorization = 'Basic '.
b64_encode "$adrCheckerUser:$adrCheckerPassword";
$request->header(Authorization => $authorization );
my $ua = $trace->{user_agent};
$ua->request($request);
};
return $wsdl->compileClient(
'AdrCheckerExterne',
transport_hook => $basic_auth,
aync => 1,
);
};
my $client = clientFactory;
my $check = $client->(
Params => {
MaxRows => 100,
CallUser => $adrCheckerUser,
SearchLanguage => 1,
SearchType => 1
},
FirstName => $first_name,
Name => ${last_name},
Street => ${street},
HouseNbr => ${nr},
Zip => ${zip},
Town => ${town},
HouseKey => 0,
PboxAddress => 0,
);
You need to add HouseKey = 0 to your adrRequest. This is a required input - you can just set it to 0 if you do not know it. Otherwise the service will return an error.
Related
I am attempting to mock out my SignalR hub for some unit tests. I am running into an issue on my Hubs OnConnectedAsync() call due to using a header to auto join a group if it exists. My issue is lying with the fact that the HubCallerContext.GetHttpContext() method is an extension method and cant be mocked. I dunno if there is a work around to this and I cant seem to find any similarly posted question about this.
OnConnectedAsync() Segment
Context.GetHttpContext().Request.Headers.TryGetValue(SignalRHeaders.GroupHeader, out StringValues header);
if (header.Any())
{
await Groups.AddToGroupAsync(Context.ConnectionId, SignalRConstants.Group);
}
Base Test Class
public DefaultHubBaseTest()
{
var memberId = Guid.NewGuid().ToString();
var orgId = Guid.NewGuid().ToString();
MockClients = new Mock<IHubCallerClients>();
MockClientProxy = new Mock<IClientProxy>();
MockClients.Setup(clients => clients.Group(It.IsAny<string>()))
.Returns(MockClientProxy.Object);
MockGroups = new Mock<IGroupManager>();
MockGroups.Setup(x => x.AddToGroupAsync(It.IsAny<string>(), It.IsAny<string>(), default(CancellationToken))).Returns(Task.CompletedTask);
MockGroups.Setup(x => x.RemoveFromGroupAsync(It.IsAny<string>(), It.IsAny<string>(), default(CancellationToken))).Returns(Task.CompletedTask);
Mock<HttpRequest> MockRequest = new Mock<HttpRequest>();
MockRequest.Setup(x => x.Headers).Returns(new HeaderDictionary()
{
{ SignalRHeaders.GroupHeader, orgId },
{ SignalRHeaders.GroupAdminHeader, "t" },
});
Mock<HttpContext> MockHttpContext = new Mock<HttpContext>();
MockHttpContext.Setup(x => x.Request).Returns(MockRequest.Object);
MockContext = new Mock<HubCallerContext>();
MockContext.Setup(x => x.ConnectionId).Returns("1");
MockContext.Setup(x => x.User.Claims).Returns(new List<Claim>() { new Claim(SignalRConstants.AzureAuthOID, memberId) });
MockContext.Setup(x => x.GetHttpContext()).Returns(MockHttpContext.Object);
DefaultHub = new DefaultHub()
{
Context = MockContext.Object,
Groups = MockGroups.Object,
Clients = MockClients.Object,
};
}
If anyone could help me with this, I would greatly appreciate it. Thanks!
I fixed the error of Request rate is large from CosmosDB by adding the new ConnectionPolicy() variable:
var client = new DocumentClient(new Uri(endpointUri), primaryKey, new ConnectionPolicy()
{
MaxConnectionLimit = 100,
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
RetryOptions = new RetryOptions() { MaxRetryAttemptsOnThrottledRequests = 3, MaxRetryWaitTimeInSeconds = 60 }
});
But I was wondering how can we do unit test to make sure it is actually working?
I am thinking of mocking the DocumentClient and set it up with heavy load. But I am not sure what the syntax should be like..
Here are the sample unit test code for the happy case:
var mockDocumentQuery = new Mock<IFakeDocumentQuery<BookModel>>();
mockDocumentQuery
.SetupSequence(_ => _.HasMoreResults)
.Returns(true)
.Returns(false);
mockDocumentQuery
.Setup(_ => _.ExecuteNextAsync<BookModel>(It.IsAny<CancellationToken>()))
.ReturnsAsync(response);
var provider = new Mock<IQueryProvider>();
provider
.Setup(_ => _.CreateQuery<BookModel>(It.IsAny<Expression>()))
.Returns(mockDocumentQuery.Object);
mockDocumentQuery.As<IQueryable<BookModel>>().Setup(x => x.Provider).Returns(provider.Object);
mockDocumentQuery.As<IQueryable<BookModel>>().Setup(x => x.Expression).Returns(dataSource.Expression);
mockDocumentQuery.As<IQueryable<BookModel>>().Setup(x => x.ElementType).Returns(dataSource.ElementType);
mockDocumentQuery.As<IQueryable<BookModel>>().Setup(x => x.GetEnumerator()).Returns(() => dataSource.GetEnumerator());
var client = new Mock<IDocumentClient>();
client.Setup(_ => _.CreateDocumentQuery<BookModel>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);
In the last line of code, how can I setup the DocumentClient with a heavy load?
I am beginner for webservice. I am writing a webservice in Moodle.
I would like to write one service for user sign up. In this case that user will not have any token or username+password.
How we can allow this user to call core_user_createUsers web service for sign up?
For other services I am using this code:
$domainname = 'http://mydomain/moodle';
require_once('./curl.php');
$curl = new curl;
$authurl = $domainname .'/login/token.php?username=admin&password=Admin123$&service=shcs_services';
$resp = $curl->get($authurl);
if($resp)
{
$resp = json_decode($resp);
$authToken = $resp->token;
}
/// PARAMETERS
$serverurl = $domainname . '/webservice/rest/server.php';
$params['wstoken'] = $authToken;
$params['wsfunction'] = 'core_user_createUsers';
$params['moodlewsrestformat'] = 'json';
$user1 = new stdClass();
$user1->username = 'testusername';
$user1->password = 'Testpassword1%';
$user1->firstname = 'testfirstname1';
$user1->lastname = 'testlastname1';
$user1->email = 'testemail1#moodle.com';
$user1->auth = 'manual';
$user1->idnumber = 'testidnumber1';
$user1->lang = 'en';
$user1->theme = 'standard';
$user1->timezone = '-12.5';
$user1->mailformat = 0;
$user1->description = 'Hello World!';
$user1->city = 'testcity1';
$user1->country = 'au';
$preferencename1 = 'preference1';
$preferencename2 = 'preference2';
$user1->preferences = array(
array('type' => $preferencename1, 'value' => 'preferencevalue1'),
array('type' => $preferencename2, 'value' => 'preferencevalue2'));
$users = array($user1);
$params['users'] = $users;
$resp = $curl->post($serverurl, $params);
echo $resp;
in above code I would like to skip the below part
$authurl = $domainname .'/login/token.php?username=admin&password=Admin123$&service=shcs_services';
$resp = $curl->get($authurl);
if($resp)
{
$resp = json_decode($resp);
$authToken = $resp->token;
}
so that I don't want to pass the value $params['wstoken'] = $authToken; to web service .
But it is not allowing me without the token. Here's the error I get:
{"exception":"moodle_exception","errorcode":"invalidtoken","message":"Invalid token - token not found"}
Token is the only way to connect the web service to with your app. It is must. As I am working nowadays on web services and mobile app. So I experienced that token is the only way to validate the web services. The first step to connect with web service by validating it. And you are not passing the token at all. So your validation is going to be failed. and you are getting this error.
I read, i try, i looking informations about how add / update combinations by webservice, in presta 1.5.3 but still i don't know how to do that.
Can someone help me?
Assigning combinations to products via Webservice is a multi-step operation (unlike CSV import).
given a product with id_product
add product_options (BO Attribute Names)
add product_option_values (BO Attribute Values) to product_options
add combinations while specifying id_product
Start by initialising PrestaShopWebservice with DEBUG=true:
$api = new PrestaShopWebservice($psShopUrl, $psAuthKey, $psDebug);
Instead of building the XML from scratch get a template for the resource you need like this:
$sxml = $api->get(array('url' => $psShopUrl.'api/'.$resource.'?schema=blank'));
The response is a SimpleXMLElement which is a easier to manipulate than DOM.
NB: The response contains all wrapper nodes and you must send the same back in your request i.e. PSWebServiceLibrary will not recreate them for you.
<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<combination>
...
</combination>
</prestashop>
SXML manipulation example:
$schema = $api->get(array('url' => $psShopUrl.'api/product_options?schema=blank'));
$data = $schema->children()->children();
$data->is_color_group = false;
$data->group_type = $group_type; // radio, select
$data->name->language[0] = 'attribute private name';
$data->public_name->language[0] = 'attribute public name';
$xml = $schema->asXML(); // all of it!
$ret = $api->add(array('resource' => 'product_options', 'postXml' => $xml));
$id_attribute_group = (int)$ret->children()->children()->id; // save for next step
Then get product_option_values schema, set data and the id_attribute_group from previous step. And so on.
Updating is the same except you will get the resource by id and then edit:
$sxml = $api->get(array('resource' => $resource, 'id' => $id));
...
$ret = $api->edit(array('resource' => $resource, 'id' => $id, 'putXml' => $xml));
As for adding multiple id values to the product_option_values node in the combinations resource you can use the array_push shortcut []:
$data->associations->product_option_values->product_option_values[]->id = 123;
$data->associations->product_option_values->product_option_values[]->id = 456;
This is work fine for me :
$webService = new PrestaShopWebservice($url, $api_key, FALSE);
$xml = $webService->get(array('url' => $url .'/api/combinations?schema=blank'));
$resources = $xml->children()->children();
$resources->id_product = $ps_product_id;
$resources->wholesale_price = $wholesale_price;
$resources->price = $price;
$resources->unit_price_impact = $unit_price_impact;
$resources->minimal_quantity = $minimal_quantity;
$resources->quantity = $quantity;
$resources->weight = $weight;
$resources->associations->product_option_values->product_option_value[0]->id = $color_id;
$resources->associations->product_option_values->product_option_value[1]->id = $size_id;
$request = $xml->asXML();
//This is a function that curl request to specific URL using method (POST)
$response = ps_curl($url . '/api/combinations', $request, 'POST', $api_key);
$xml_load = simplexml_load_string($response);
$id = $xml_load->combination->id;
I hope that's helpful :)
Can someone take a look at this code and tell me if there's any obvious reason it shouldn't be working? When service.getResponse is called within my code the mocking framework only returns null, not the object I specified.
[Test]
public void Get_All_Milestones()
{
var mockRepo = new MockRepository();
var service = mockRepo.DynamicMock<IRestfulService>();
var request = new RestRequestObject
{
Password = "testpw!",
UserName = "user",
SecureMode = true,
Url = "www.updatelog.com/",
Command = String.Format("projects/{0}/milestones/list", 123456),
Method = "POST"
};
var response = new RestResponseObject
{
StatusCode = 200,
ErrorsExist = false,
Response =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<milestones type=\"array\">\n <milestone>\n <completed type=\"boolean\">false</completed>\n <created-on type=\"datetime\">2008-10-02T17:37:51Z</created-on>\n <creator-id type=\"integer\">3028235</creator-id>\n <deadline type=\"date\">2008-10-20</deadline>\n <id type=\"integer\">7553836</id>\n <project-id type=\"integer\">123456</project-id>\n <responsible-party-id type=\"integer\">3028295</responsible-party-id>\n <responsible-party-type>Person</responsible-party-type>\n <title>Atb2 Editor Substantially Done</title>\n <wants-notification type=\"boolean\">true</wants-notification>\n </milestone>\n</milestones>\n"
};
using(mockRepo.Record())
{
Expect
.Call(service.GetResponse(request))
.Return(response);
}
using(mockRepo.Playback())
{
var dal = new DataAccess(service);
var result = dal.GetMilestones(123456);
Assert.IsNotNull(result, "The result should not be null.");
Assert.AreNotEqual(0, result.Count, "There should be exactly one item in this list.");
Assert.AreEqual(123456, result[0].ProjectId, "The project ids don't match.");
Assert.AreEqual(7553836, result[0].Id, "The ids don't match.");
}
mockRepo.VerifyAll();
}
A dynamic mock will return null if the input data does not match the expected, so my guess would be that your code is calling service.GetResponse() with different values for the RestRequestObject or that equality for the RestRequestObject does not work as you expect it to.
I think I would try replacing the dynamic mock with a strict mock and look at the error Rhino Mocks returns.