I'm quite new to ElasticSearch and just figuring some things out for now, but here is a problem. After all the trouble of changing the server we migrated the nodes, but have some missing data in one of them. We have two nodes that have records with the same ID in both of them. In 1'st one everything is ok, but in second some records seems to be missing. For example if I send the request like this:
GET /fnh_detailbeta/main/61UkVww8QGu093RirFG84A
I will get the following error (in Marvel - Sense)
{
"error": "NoShardAvailableActionException[[fnh_detailbeta][0] null]",
"status": 503
}
So, what I'm trying to do now is compare all the records in Node 1 with records in Node 2 via ElasticSearch PHP. Here is the PHP I'm trying to run:
<?php
require '../connector/vendor/autoload.php';
$number = 1;
$params = array();
$params['hosts'] = array (
'146.185.164.121:9200', // IP + Port
);
$client = new Elasticsearch\Client($params);
$getParams = array();
$getParams['index'] = 'fnh_mainbeta';
$getParams['type'] = 'main';
//REQUEST AMOUNT
$json = '{"query": {"match_all": {}},"size": 1,"from":'.$number.'}';
$getParams['body'] = $json;
$retDoc = $client->search($getParams);
$total = $retDoc['hits']['total'];
//END OF REQUEST AMOUNT
//REQUEST ID
for ($i = 1; $i <= $total; $i++) {
$json = '{"query": {"match_all": {}},"size": 1,"from":'.$number.'}';
$getParams = array();
$getParams['index'] = 'fnh_mainbeta';
$getParams['type'] = 'main';
$getParams['body'] = $json;
$getParams['ignore'] = 503;
$getParams['ignore'] = 404;
$retDoc = $client->search($getParams);
$found_id = $retDoc['hits']['hits'][0]['_id'];
echo $found_id;
//REGUEST SECOND DB
$getParams = array();
$getParams['index'] = 'fnh_detailbeta';
$getParams['type'] = 'main';
$getParams['id'] = '61UkVww8QGu093RirFG84A';
$retDoc = $client->get($getParams);
$found_id_two = $retDoc['_id'];
echo $found_id_two;
//END OF REQUEST SECOND DB
$number++;
sleep(1);
};
//END OF REQUEST AMOUNT
It is not finished by now, but I get the fatal error that exits the script:
Fatal error: Uncaught exception 'Guzzle\Http\Exception\ServerErrorResponseException' with message 'Server error response
[status code] 503
[reason phrase] Service Unavailable
This error appears when NoShardAvailableActionException[[fnh_detailbeta][0] null]... So, the question is:
What is the best way to catch this error (something like IF error THEN echo "error") without stop of the PHP execution. In other words - I want to determine this error, delete this record and go further comparing the Nodes.
Any help will be appreciated!
Related
I have a problem with Firefox 45. It's always saying $_FILES['imagem'] is undefined and is null, even having images already previously selected and shown from the database. Only in version 45, which I believe to be a bug.
The editing process is called via Ajax, and thank to this error, the ajax keeps loading forever. I'd like to know if there's a way to stop its process and show an error in the view.
$FILES = $_FILES;
$count = count($_FILES['imagem']['name']) - 2;
for ($i = 0; $i <= $count; $i++) {
$_FILES['imagem']['name'] = $FILES['imagem']['name'][$i];
$_FILES['imagem']['name'] = $FILES['imagem']['name'][$i];
$_FILES['imagem']['type'] = $FILES['imagem']['type'][$i];
$_FILES['imagem']['tmp_name'] = $FILES['imagem']['tmp_name'][$i];
$_FILES['imagem']['error'] = $FILES['imagem']['error'][$i];
$_FILES['imagem']['size'] = $FILES['imagem']['size'][$i];
if (isset($_FILES['imagem']) && $_FILES['imagem']['name'] !== '') {
$config['file_name'] = $id . '_' . $_FILES['imagem']['name'];
$config['upload_path'] = './uploads/carros/imagens/';
$config['allowed_types'] = 'jpg|jpeg|png';
$config['overwrite'] = true;
$imagem = array();
$imagem['id_carro'] = $id;
$imagem['imagem'] = $config['file_name'];
$this->upload->initialize($config);
$this->upload->do_upload('imagem');
$this->Imagens_carro_model->insert($imagem);
}
//
// Apagar caso haja.
if ($this->input->post('nome_imagem')[$i] === '') {
$this->Imagens_carro_model->delete($this->input->post('id_imagem')[$i]);
}
}
Above is part of the code where the error is generated:
Severity: Notice
Message: Undefined index: imagem
Filename: controllers/Carros.php
Line Number: 161
...
I guess I can't do anything with error because it actually succeeds, and the error occurs in PHP part, when it didn't find imagem index. Suggestions?
You may check the response if you send a curated response from your PHP, for example, on a successful operation send a json response like (This might not be the accurate answer to the question but an idea to help the OP with ajax error handling ideas):
if(somethingWasSuccessfull) {
$response = [
'success' => true,
'message' => 'something was successful!'
];
}
else {
$response = [
'success' => false,
'message' => 'something was not successful!'
];
}
echo json_encode(($response);
So, when you recieve the response on done/success callback on your client side you can check the value of success, for example:
$.ajax(...)
.done(function(response) {
// Request succeeded
// Probably parse the response
if(response.success) {
// Successfull, status code is 200
}
else {
// Not successfull, status code is 200
}
})
.fail(function(response) {
// Error happened..., status code is not 200
})
.always(function(response) {
// Perform some common tasks
});
EDIT : Already fixed the error Creating default object from empty value . My question now is just suggestions how to make this process better.
I am making a tool that sends batch API request to a certain URL. I am using https://github.com/stil/curl-easy for batch API request That API will validate the phone numbers I am sending and return a result. That API can support maximum 20 request per second, supposed I have 50,000 API request, what is the best and fastest way to process things?
The current process is, I query to my database for the number of records I have which is the number of phone numbers. Then I make a loop with the number of phone numbers. Inside a single iteration, I will query 13 records from the database then pass it to the queue and process it, when the processing is finished I will query again to the database and update the fields for the the phone number based on the API response. My problem is that I think I have a logic error on my loop when I run this the processing will stop for sometime and gives me:
Creating default object from empty value
I guess that is because of my loop here's my code.
public function getParallelApi()
{
$numItems = DB::connection('mysql')->select("SELECT COUNT(ID) AS cnt FROM phones WHERE status IS NULL");
for($y = 0; $y < $numItems[0]->cnt; $y++)
{
$queue = new \cURL\RequestsQueue;
// Set default options for all requests in queue
$queue->getDefaultOptions()
->set(CURLOPT_TIMEOUT, 5)
->set(CURLOPT_RETURNTRANSFER, true)
->set(CURLOPT_SSL_VERIFYPEER, false);
// This is the function that is called for every completed request
$queue->addListener('complete', function (\cURL\Event $event) {
$response = $event->response;
$json = $response->getContent(); // Returns content of response
$feed = json_decode($json, true);
$phone_number = $feed['msisdn'];
if(isset($phone_number))
{
$status = "";$remarks = "";$network = ""; $country = "";$country_prefix = "";
if(isset($feed['status']))
{
$status = $feed['status'];
}
if(isset($feed['network']))
{
$network = $feed['network'];
}
if(isset($feed['country']))
{
$country = $feed['country'];
}
if(isset($feed['country_prefix']))
{
$country_prefix = $feed['country_prefix'];
}
if(isset($feed['remark']))
{
$remarks = $feed['remark'];
}
$update = Phone::find($phone_number);
$update->network = $network;
$update->country = $country;
$update->country_prefix = $country_prefix;
$update->status = $status;
$update->remarks = $remarks;
$update->save();
}
});
// Get 13 records
$phone = DB::connection('mysql')->select("SELECT * FROM phones WHERE status IS NULL LIMIT 13");
foreach ($phone as $key => $value)
{
$request = new \cURL\Request($this->createCurlUrl($value->msisdn));
// var_dump($this->createCurlUrl($value->msisdn)); exit;
// Add request to queue
$queue->attach($request);
}
// Process the queue
while ($queue->socketPerform()) {
$queue->socketSelect();
}
sleep(2);
$y += 13; // Move to the next 13 records
}
Session::flash('alert-info', 'Data Updated Successfully!');
return Redirect::to('upload');
}
Since the maximum is 20 request per seconds I'm just doing it 13 request per second just to be sure I won't clog their server. I am adding sleep(2); to pause a bit so that I can make sure that the queue is fully processed before moving on.
I use James Armes's PHP-EWS library.
The following code works fine with single attachments, but fails with multiply files.
<?php
$msgRequest->MessageDisposition = 'SaveOnly';
$msgResponse = $ews->CreateItem($msgRequest);
$msgResponseItems = $msgResponse->ResponseMessages->CreateItemResponseMessage->Items;
// Create attachment(s)
$attachments = array();
$i = 0;
foreach ($message_details['attachment'] as $attachment) {
$attachments[$i] = new EWSType_FileAttachmentType();
$attachments[$i]->Content = file_get_contents($attachment['path'] . '/' . $attachment['file']);
$attachments[$i]->Name = $attachment['file'];
$i++;
}
//
// Attach files to message
$attRequest = new EWSType_CreateAttachmentType();
$attRequest->ParentItemId = $msgResponseItems->Message->ItemId;
$attRequest->Attachments = new EWSType_NonEmptyArrayOfAttachmentsType();
$attRequest->Attachments->FileAttachment = $attachments;
$attResponse = $ews->CreateAttachment($attRequest);
$attResponseId = $attResponse->ResponseMessages->CreateAttachmentResponseMessage->Attachments->FileAttachment->AttachmentId;
// Save message id from create attachment response
$msgItemId = new EWSType_ItemIdType();
$msgItemId->ChangeKey = $attResponseId->RootItemChangeKey;
$msgItemId->Id = $attResponseId->RootItemId;
// Send and save message
$msgSendRequest = new EWSType_SendItemType();
$msgSendRequest->ItemIds = new EWSType_NonEmptyArrayOfBaseItemIdsType();
$msgSendRequest->ItemIds->ItemId = $msgItemId;
$msgSendRequest->SaveItemToFolder = true;
$msgSendResponse = $ews->SendItem($msgSendRequest);
$response = $msgSendResponse->ResponseMessages->SendItemResponseMessage;
?>
$ews->SendItem() returns this error:
Uncaught SoapFault exception: [a:ErrorSchemaValidation] The request
failed schema validation: The required attribute 'Id' is missing.
What do I miss here?
Found the answer here:
https://github.com/jamesiarmes/php-ews/issues/132
Basically Exchange does not use an array if there is only one attachment, so an additional check is required to determine where to get the ID from.
if(!is_array($attResponse->ResponseMessages->CreateAttachmentResponseMessage))
$attResponseId = $attResponse->ResponseMessages->CreateAttachmentResponseMessage->Attachments->FileAttachment->AttachmentId;
else {
$attResponseId = $attResponse->ResponseMessages->CreateAttachmentResponseMessage[0]->Attachments->FileAttachment->AttachmentId;
}
Exchange uses the same structure with recipients. I find this inconsistent, however I am sure there is a reason behind it.
I hope someone will benefit from raising this.
I'm getting an error message when making a call to an xBase++ based web server that is acting as a web service (not using WSDL) when trying to make a soapclient call to it using NuSoap 1.94 with PHP 5.2.17. This exact same code works with NuSOAP 1.94 on PHP 4. Any ideas or help would be appreciated!
Note (I had to remove the https:// part of the addresses from the error message below - I was getting an error posting saying I needed 10 reputation to post 2 links or more)
Thanks,
Salar
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'xxx.xxx.com:55055' : failed to load external entity "xxx.xxx.com:55055" in /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php:34 Stack trace: #0 /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php(34): SoapClient->SoapClient('https://xxx.xxx...') #1 /hsphere/local/home/xxx/xxx.com/phpinvent/xmsgtest.php(15): XMsg('LOGIN', Array) #2 {main} thrown in /hsphere/local/home/xxx/xxx.com/phpinvent/inc/functions/xmsg.php on line 34
Here's the code of my test page, and the xmsg function:
<?php
ini_set('display_errors', 'On');
ini_set('default_socket_timeout', 300);
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// include configuration
require_once('inc/config.php');
require_once('inc/nusoap/nusoap.php'); // include the NuSOAP classes
$xmsg_param[0][0] = "userid";
$xmsg_param[0][1] = "TEST";
$xmsg_param[1][0] = "password";
$xmsg_param[1][1] = "TEST";
$result = XMsg("LOGIN", $xmsg_param);
echo("<br>resulttxt: ".$result['xmsg_resulttxt']);
echo("<br>Sessionid: ".$result['sessionid']);
?>
<?php
// XMsg *************************************************************************
// This function is used to send a message through the robust, connectionless message system
function XMsg($xm_type, $xm_parameters, $xm_target = XMSG_DEFAULT_GATEWAY, $xm_mode = XMSG_DEFAULT_MODE)
{
// Parameters:
// xm_type - C - mandatory – type of message being sent
// xm_parameters - A - optional - 2 dimensional array of name/value pairs that will be sent to the target with the message
// xm_target - C - optional - target - currently supports only URLs of AutoMate agents - defaults to gateway
// xm_mode - C - optional - tokens that allow for modification of the message - currently defaults to #SOAP# to send via SOAP
// Returns:
// xm_result - A - array of name/value pairs returned from the target in same format as xm_target
$xm_SOAPagent = ''; // SOAP Envelope Object - Request
$xm_SOAPresult = ''; // SOAP Envelope Object - Response
$xm_SOAPclass = '';
$xm_retrynum = 0; // Number of retries attempted
$xm_retry = true; // Continue retrying?
$xm_result = Array(); // Array of results returned by XMsg
$xm_numparams = 0; // Number of parameters passed to XMsg
$xm_I = 0; // FOR Loop Counter
// Initialize Parameters
$xm_parameters = (gettype($xm_parameters) == "array" ? $xm_parameters : array());
// check if mandatory parameters are passed
// xm_type must be character and not empty
if (gettype($xm_type)=="string" && !empty($xm_type)) {
switch($xm_mode)
{
case "SOAP":
// open SOAP envelope and initialize
echo("calling xm_target: ".$xm_target."<br>");
$soapclient = new soapclient($xm_target);
$soapparam = array();
// create and pass xmsg structure - NOTE: this section is specialized to PHP
$soapparam['xmsg_id'] = '';
$soapparam['xmsg_source'] = '';
$soapparam['xmsg_target'] = $xm_target;
$soapparam['xmsg_session'] = $_SESSION['SESSIONID'];
$soapparam['xmsg_userid'] = $_SESSION['USERID'];
$soapparam['xmsg_websessid'] = session_id();
$soapparam['xmsg_ip'] = $_SERVER['REMOTE_ADDR'];
$soapparam['xmsg_status'] = 'SENT';
$soapparam['xmsg_type'] = $xm_type;
$soapparam['xmsg_result'] = '';
$soapparam['xmsg_resulttxt'] = '';
$soapparam['xmsg_date'] = date("m/d/y");
$soapparam['xmsg_time'] = date("H:i:s");
$soapparam['xmsg_datereceive'] = '';
$soapparam['xmsg_timereceive'] = '';
$soapparam['xmsg_dateresponse'] = '';
$soapparam['xmsg_timeresponse'] = '';
// count parameters and add to SOAP Envelope
$xm_numparams = count($xm_parameters);
for ($xm_I = 0; $xm_I < $xm_numparams; $xm_I++) {
echo("setting soapparam[".$xm_parameters[$xm_I][0]."] to :".$xm_parameters[$xm_I][1]);
$soapparam[$xm_parameters[$xm_I][0]] = $xm_parameters[$xm_I][1];
}
// SOAP retry loop start - retry until xm_retry is false - set to false when call succeeds or max # retries exceeded
do {
// run remote SOAP call for RemoteCall as specified in
$xm_result = $soapclient->call('XMsg',$soapparam);
// check for fault
echo ("Fault: ".$xm_result['FAULT']."<br>");
echo ("1 Faultcode: ".$xm_result['faultcode']."<br>");
if (empty($xm_result['faultcode'])) {
echo('<hr>'.'<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>');
echo('<hr>'.'<pre>' . htmlspecialchars($soapclient->debug_str, ENT_QUOTES) . '</pre>');
$xm_retry = false;
// update status / response date / time
$xm_result['xmsg_status'] = "RECEIVED";
$xm_result['xmsg_dateresponse'] = date("m/d/y");
$xm_result['xmsg_timeresponse'] = date("H:i:s");
} else {
echo("2 faultcode: ".$xm_result['faultcode']);
}
// SOAP Call retry handling
if ($xm_retry) {
// increase the SOAP comm retry counter to count the number of retries made
$xm_retrynum++;
// check if the maximum number of retries has been reached
if ($xm_retrynum <= XMSG_NUMRETRY) {
sleep(XMSG_RETRYDELAY); // delay for set number of seconds
} else {
$xm_retry = false;
}
}
} while ($xm_retry);
break;
default:
// no other message type handling currently
}
}
}
return $xm_result;
// XMsg *************************************************************************
This is quite simple. Your web server can't see the location the WSDL is hosted at. Can you hit the location if you copy the WSDL url and paste it into your browser? You should check that the URL you are using is correct, and whether your web server can even see that location. If not you will need to remedy that before it will work.
I'm using the following code to turn user's IP into latitude/longitude information using the hostip web service:
//get user's location
$ip=$_SERVER['REMOTE_ADDR'];
function get_location($ip) {
$content = file_get_contents('http://api.hostip.info/?ip='.$ip);
if ($content != FALSE) {
$xml = new SimpleXmlElement($content);
$coordinates = $xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->ipLocation->children('gml', TRUE)->pointProperty->Point->coordinates;
$longlat = explode(',', $coordinates);
$location['longitude'] = $longlat[0];
$location['latitude'] = $longlat[1];
$location['citystate'] = '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->children('gml', TRUE)->name;
$location['country'] = '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->countryName;
return $location;
}
else return false;
}
$data = get_location($ip);
$center_long=$data['latitude'];
$center_lat=$data['longitude'];
This works fine for me, using $center_long and $center_lat the google map on the page is centered around my city, but I have a friend in Thailand who tested it from there, and he got this error:
Warning: get_location() [function.get-location]: Node no longer exists in /home/bedbugs/registry/index.php on line 21
So I'm completely confused by this, how could he be getting an error if I don't? I tried googling it and it has something to do with parsing XML data, but the parsing process is the same for me and him. Note that line 21 is the one that starts with '$coordinates =' .
You need to check the service actually has an <ipLocation> listed, you're doing:
$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->ipLocation
->children('gml', TRUE)->pointProperty->Point->coordinates
but the XML output for my IP is:
<HostipLookupResultSet version="1.0.1" xsi:noNamespaceSchemaLocation="http://www.hostip.info/api/hostip-1.0.1.xsd">
<gml:description>This is the Hostip Lookup Service</gml:description>
<gml:name>hostip</gml:name>
<gml:boundedBy>
<gml:Null>inapplicable</gml:Null>
</gml:boundedBy>
<gml:featureMember>
<Hostip>
<ip>...</ip>
<gml:name>(Unknown City?)</gml:name>
<countryName>(Unknown Country?)</countryName>
<countryAbbrev>XX</countryAbbrev>
<!-- Co-ordinates are unavailable -->
</Hostip>
</gml:featureMember>
</HostipLookupResultSet>
The last part ->children('gml', TRUE)->pointProperty->Point->coordinates gives the error because it has no children (for some IPs).
You can add a basic check to see if the <ipLocation> node exists like this (assuming the service always returns at least up to the <hostIp> node):
function get_location($ip) {
$content = file_get_contents('http://api.hostip.info/?ip='.$ip);
if ($content === FALSE) return false;
$location = array('latitude' => 'unknown', 'longitude' => 'unknown');
$xml = new SimpleXmlElement($content);
$hostIpNode = $xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip;
if ($hostIpNode->ipLocation) {
$coordinates = $hostIpNode->ipLocation->children('gml', TRUE)->pointProperty->Point->coordinates;
$longlat = explode(',', $coordinates);
$location['longitude'] = $longlat[0];
$location['latitude'] = $longlat[1];
}
$location['citystate'] = '==>'.$hostIpNode->children('gml', TRUE)->name;
$location['country'] = '==>'.$hostIpNode->countryName;
return $location;
}