2021-09-20 10:39:03 +00:00
< ? php
namespace App\Jobs ;
use Illuminate\Bus\Queueable ;
2023-07-26 09:44:07 +00:00
use Illuminate\Contracts\Queue\ShouldBeUnique ;
2021-09-20 10:39:03 +00:00
use Illuminate\Contracts\Queue\ShouldQueue ;
use Illuminate\Foundation\Bus\Dispatchable ;
use Illuminate\Queue\InteractsWithQueue ;
2023-07-26 09:44:07 +00:00
use Illuminate\Queue\ManuallyFailedException ;
use Illuminate\Queue\MaxAttemptsExceededException ;
2021-09-20 10:39:03 +00:00
use Illuminate\Queue\SerializesModels ;
use Illuminate\Support\Facades\Log ;
2023-07-26 09:44:07 +00:00
use Illuminate\Support\Facades\Notification ;
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
use App\Classes\Protocol ;
2021-09-20 10:39:03 +00:00
use App\Classes\Protocol\ { Binkp , EMSI };
2024-06-01 02:55:27 +00:00
use App\Classes\Sock\Exception\SocketException ;
2021-09-20 10:39:03 +00:00
use App\Classes\Sock\SocketClient ;
2023-07-07 13:59:04 +00:00
use App\Models\ { Address , Mailer , Setup };
2023-07-26 09:44:07 +00:00
use App\Notifications\Netmails\PollingFailed ;
2023-11-27 04:56:28 +00:00
use App\Traits\ObjectIssetFix ;
2021-09-20 10:39:03 +00:00
2023-07-26 09:44:07 +00:00
class AddressPoll implements ShouldQueue , ShouldBeUnique
2021-09-20 10:39:03 +00:00
{
2023-11-27 04:56:28 +00:00
use Dispatchable , InteractsWithQueue , Queueable , SerializesModels , ObjectIssetFix ;
2023-07-26 09:44:07 +00:00
2023-11-27 04:56:28 +00:00
private const LOGKEY = 'JAP' ;
2023-07-26 09:44:07 +00:00
2023-11-27 04:56:28 +00:00
public int $tries = 5 ;
public int $maxExceptions = 1 ;
public bool $failOnTimeout = TRUE ;
2023-07-26 09:44:07 +00:00
public const QUEUE = 'poll' ;
2021-09-20 10:39:03 +00:00
private Address $ao ;
2023-07-07 13:59:04 +00:00
private ? Mailer $mo ;
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
public function __construct ( Address $ao , Mailer $mo = NULL )
2021-09-20 10:39:03 +00:00
{
$this -> ao = $ao ;
2023-07-07 13:59:04 +00:00
$this -> mo = $mo ;
2023-07-26 09:44:07 +00:00
$this -> onQueue ( self :: QUEUE );
}
public function __get ( $key ) : mixed
{
switch ( $key ) {
case 'address' :
return $this -> ao ;
2024-05-21 11:10:58 +00:00
case 'jobname' :
2023-07-26 09:44:07 +00:00
return $this -> ao -> ftn ;
default :
return NULL ;
}
}
/**
* Time to wait between tries
*
* @ return int [] in seconds
*/
public function backoff () : array
{
return [
60 * 5 , // 5 mins
60 * 60 , // 1 hr
60 * 60 * 6 , // 6 hrs
60 * 60 * 12 // 12 hrs
];
2021-09-20 10:39:03 +00:00
}
/**
* When calling MessageProcess - we assume that the packet is from a valid source
*/
public function handle ()
{
2023-07-26 09:44:07 +00:00
if ( ! $this -> ao -> system -> mailer_preferred -> count () || ( $this -> mo && ( ! $this -> ao -> system -> mailer_preferred -> find ( $this -> mo )))) {
$this -> fail ( 'Missing mailer details' );
return ;
}
Log :: info ( sprintf ( '%s:- Polling [%s] - attempt [%d]' , self :: LOGKEY , $this -> ao -> ftn , $this -> attempts ()));
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
foreach ( $this -> ao -> system -> mailer_preferred as $o ) {
// If we chose a protocol, skip to find the mailer details for it
if ( $this -> mo && ( $o -> id !== $this -> mo -> id ))
continue ;
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
switch ( $o -> name ) {
case 'BINKP' :
$s = new Binkp ( Setup :: findOrFail ( config ( 'app.id' )));
2023-12-10 08:07:53 +00:00
$mo = Mailer :: where ( 'name' , 'BINKP' ) -> singleOrFail ();
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
break ;
2021-09-20 10:39:03 +00:00
2023-07-07 13:59:04 +00:00
case 'EMSI' :
$s = new EMSI ( Setup :: findOrFail ( config ( 'app.id' )));
2023-12-10 08:07:53 +00:00
$mo = Mailer :: where ( 'name' , 'EMSI' ) -> singleOrFail ();
2023-07-07 13:59:04 +00:00
break ;
default :
2023-07-26 09:44:07 +00:00
$this -> fail ( 'Mailer type unhandled' );
return ;
2023-07-07 13:59:04 +00:00
}
2023-07-26 09:44:07 +00:00
Log :: info ( sprintf ( '%s:- Trying a [%s] session to [%s:%d] (%s)' ,
self :: LOGKEY , $o -> name , $this -> ao -> system -> address , $o -> pivot -> port , $this -> ao -> ftn ));
2021-09-20 10:39:03 +00:00
2023-07-26 09:44:07 +00:00
try {
$client = SocketClient :: create ( $this -> ao -> system -> address , $o -> pivot -> port );
2023-12-10 08:07:53 +00:00
if (( $s -> session ( $mo , $client , $this -> ao ) & Protocol :: S_MASK ) === Protocol :: S_OK ) {
2023-07-26 09:44:07 +00:00
Log :: info ( sprintf ( '%s:= Connection ended successfully with [%s] (%s)' , self :: LOGKEY , $client -> address_remote , $this -> ao -> ftn ));
return ;
} else {
Log :: alert ( sprintf ( '%s:! Connection failed to [%s] (%s)' , self :: LOGKEY , $client -> address_remote , $this -> ao -> ftn ));
}
} catch ( SocketException $e ) {
2024-05-21 11:10:58 +00:00
Log :: error ( sprintf ( '%s:! SocketException Unable to connect to [%s]: %s' , self :: LOGKEY , $this -> ao -> ftn , $e -> getMessage ()));
2023-07-26 09:44:07 +00:00
break ;
2024-04-16 12:31:09 +00:00
} catch ( \ErrorException $e ) {
Log :: error ( sprintf ( '%s:! Unable to connect to [%s]: %s' , self :: LOGKEY , $this -> ao -> ftn , $e -> getMessage ()));
break ;
2023-07-07 13:59:04 +00:00
}
2021-09-20 10:39:03 +00:00
}
2023-07-26 09:44:07 +00:00
$delay = ( int )( $this -> backoff ()[ $this -> attempts () - 1 ] ? ? last ( $this -> backoff ()));
Log :: info ( sprintf ( '%s:= Retrying poll in %d seconds' , self :: LOGKEY , $delay ));
$this -> release ( $delay );
}
public function failed ( \Throwable $exception ) : void
{
switch ( get_class ( $exception )) {
case ManuallyFailedException :: class :
Log :: error ( sprintf ( '%s:! Address Poll failed for [%s] (%s)' , self :: LOGKEY , $this -> ao -> ftn , $exception -> getMessage ()));
break ;
case MaxAttemptsExceededException :: class :
Log :: error ( sprintf ( '%s:! Address Poll was tried too many times for [%s]' , self :: LOGKEY , $this -> ao -> ftn ));
Notification :: route ( 'netmail' , $this -> ao ) -> notify ( new PollingFailed );
$this -> ao -> system -> autohold = TRUE ;
$this -> ao -> system -> save ();
exit ( 0 );
default :
2023-07-27 11:09:57 +00:00
Log :: error ( sprintf ( '%s:! Address Poll to [%s] with an unknown exception (%s)[%s]' , self :: LOGKEY , $this -> ao -> ftn , get_class ( $exception ), $exception -> getMessage ()));
2023-07-26 09:44:07 +00:00
}
}
public function uniqueId () : string
{
2024-01-10 05:58:35 +00:00
return $this -> ao -> id ;
2021-09-20 10:39:03 +00:00
}
}