mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-21 07:41:49 -05:00
Update Client to report login status
This patch updates the aprsd client base class to report login succes and any error string associated with a login failure. Also exposes the login status so anyone using the client to check for login failure. Update webchat, listen, server commands to check for initial login failures and exit if the login failed. No reason to continue on if the login fails.
This commit is contained in:
parent
9f7d169c18
commit
06c1fb985e
@ -23,13 +23,24 @@ class APRSISClient(base.APRSClient):
|
||||
max_timeout = {"hours": 0.0, "minutes": 2, "seconds": 0}
|
||||
self.max_delta = datetime.timedelta(**max_timeout)
|
||||
|
||||
def stats(self) -> dict:
|
||||
def stats(self, serializable=False) -> dict:
|
||||
stats = {}
|
||||
if self.is_configured():
|
||||
if self._client:
|
||||
keepalive = self._client.aprsd_keepalive
|
||||
server_string = self._client.server_string
|
||||
if serializable:
|
||||
keepalive = keepalive.isoformat()
|
||||
else:
|
||||
keepalive = "None"
|
||||
server_string = "None"
|
||||
stats = {
|
||||
"server_string": self._client.server_string,
|
||||
"sever_keepalive": self._client.aprsd_keepalive,
|
||||
"connected": self.is_connected,
|
||||
"filter": self.filter,
|
||||
"keepalive": keepalive,
|
||||
"login_status": self.login_status,
|
||||
"server_string": server_string,
|
||||
"transport": self.transport(),
|
||||
}
|
||||
|
||||
return stats
|
||||
@ -99,22 +110,31 @@ class APRSISClient(base.APRSClient):
|
||||
self.connected = False
|
||||
backoff = 1
|
||||
aprs_client = None
|
||||
retries = 3
|
||||
retry_count = 0
|
||||
while not self.connected:
|
||||
retry_count += 1
|
||||
if retry_count >= retries:
|
||||
break
|
||||
try:
|
||||
LOG.info(f"Creating aprslib client({host}:{port}) and logging in {user}.")
|
||||
aprs_client = aprsis.Aprsdis(user, passwd=password, host=host, port=port)
|
||||
# Force the log to be the same
|
||||
aprs_client.logger = LOG
|
||||
aprs_client.connect()
|
||||
self.connected = True
|
||||
self.connected = self.login_status["success"] = True
|
||||
self.login_status["message"] = aprs_client.server_string
|
||||
backoff = 1
|
||||
except LoginError as e:
|
||||
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
|
||||
self.connected = False
|
||||
self.connected = self.login_status["success"] = False
|
||||
self.login_status["message"] = e.message
|
||||
LOG.error(e.message)
|
||||
time.sleep(backoff)
|
||||
except Exception as e:
|
||||
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
|
||||
self.connected = False
|
||||
self.connected = self.login_status["success"] = False
|
||||
self.login_status["message"] = e.message
|
||||
time.sleep(backoff)
|
||||
# Don't allow the backoff to go to inifinity.
|
||||
if backoff > 5:
|
||||
@ -135,5 +155,7 @@ class APRSISClient(base.APRSClient):
|
||||
except Exception as e:
|
||||
LOG.error(e)
|
||||
LOG.info(e.__cause__)
|
||||
raise e
|
||||
else:
|
||||
LOG.warning("client is None, might be resetting.")
|
||||
self.connected = False
|
||||
|
@ -19,6 +19,10 @@ class APRSClient:
|
||||
_client = None
|
||||
|
||||
connected = False
|
||||
login_status = {
|
||||
"success": False,
|
||||
"message": None,
|
||||
}
|
||||
filter = None
|
||||
lock = threading.Lock()
|
||||
|
||||
@ -38,6 +42,18 @@ class APRSClient:
|
||||
dict: Statistics about the connection and packet handling
|
||||
"""
|
||||
|
||||
@property
|
||||
def is_connected(self):
|
||||
return self.connected
|
||||
|
||||
@property
|
||||
def login_success(self):
|
||||
return self.login_status.get("success", False)
|
||||
|
||||
@property
|
||||
def login_failure(self):
|
||||
return self.login_status["message"]
|
||||
|
||||
def set_filter(self, filter):
|
||||
self.filter = filter
|
||||
if self._client:
|
||||
|
@ -27,6 +27,9 @@ class Aprsdis(aprslib.IS):
|
||||
# date for last time we heard from the server
|
||||
aprsd_keepalive = datetime.datetime.now()
|
||||
|
||||
# Which server we are connected to?
|
||||
server_string = "None"
|
||||
|
||||
# timeout in seconds
|
||||
select_timeout = 1
|
||||
lock = threading.Lock()
|
||||
|
@ -14,8 +14,11 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
class APRSDFakeClient(base.APRSClient, metaclass=trace.TraceWrapperMetaclass):
|
||||
|
||||
def stats(self) -> dict:
|
||||
return {}
|
||||
def stats(self, serializable=False) -> dict:
|
||||
return {
|
||||
"transport": "Fake",
|
||||
"connected": True,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def is_enabled():
|
||||
|
@ -17,12 +17,18 @@ class KISSClient(base.APRSClient):
|
||||
|
||||
_client = None
|
||||
|
||||
def stats(self) -> dict:
|
||||
def stats(self, serializable=False) -> dict:
|
||||
stats = {}
|
||||
if self.is_configured():
|
||||
return {
|
||||
stats = {
|
||||
"connected": self.is_connected,
|
||||
"transport": self.transport(),
|
||||
}
|
||||
if self.transport() == client.TRANSPORT_TCPKISS:
|
||||
stats["host"] = CONF.kiss_tcp.host
|
||||
stats["port"] = CONF.kiss_tcp.port
|
||||
elif self.transport() == client.TRANSPORT_SERIALKISS:
|
||||
stats["device"] = CONF.kiss_serial.device
|
||||
return stats
|
||||
|
||||
@staticmethod
|
||||
|
@ -17,22 +17,4 @@ class APRSClientStats:
|
||||
|
||||
@wrapt.synchronized(lock)
|
||||
def stats(self, serializable=False):
|
||||
cl = client.client_factory.create()
|
||||
stats = {
|
||||
"transport": cl.transport(),
|
||||
"filter": cl.filter,
|
||||
"connected": cl.connected,
|
||||
}
|
||||
|
||||
if cl.transport() == client.TRANSPORT_APRSIS:
|
||||
stats["server_string"] = cl.client.server_string
|
||||
keepalive = cl.client.aprsd_keepalive
|
||||
if serializable:
|
||||
keepalive = keepalive.isoformat()
|
||||
stats["server_keepalive"] = keepalive
|
||||
elif cl.transport() == client.TRANSPORT_TCPKISS:
|
||||
stats["host"] = CONF.kiss_tcp.host
|
||||
stats["port"] = CONF.kiss_tcp.port
|
||||
elif cl.transport() == client.TRANSPORT_SERIALKISS:
|
||||
stats["device"] = CONF.kiss_serial.device
|
||||
return stats
|
||||
return client.client_factory.create().stats(serializable=serializable)
|
||||
|
@ -256,6 +256,12 @@ def listen(
|
||||
LOG.info("Creating client connection")
|
||||
aprs_client = client_factory.create()
|
||||
LOG.info(aprs_client)
|
||||
if not aprs_client.login_success:
|
||||
# We failed to login, will just quit!
|
||||
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||
LOG.error(msg)
|
||||
print(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
LOG.debug(f"Filter by '{filter}'")
|
||||
aprs_client.set_filter(filter)
|
||||
|
@ -58,6 +58,14 @@ def server(ctx, flush):
|
||||
LOG.info("Creating client connection")
|
||||
aprs_client = client_factory.create()
|
||||
LOG.info(aprs_client)
|
||||
if not aprs_client.login_success:
|
||||
# We failed to login, will just quit!
|
||||
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||
LOG.error(msg)
|
||||
print(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
# Check to make sure the login worked.
|
||||
|
||||
# Create the initial PM singleton and Register plugins
|
||||
# We register plugins first here so we can register each
|
||||
|
@ -24,7 +24,9 @@ from aprsd import utils as aprsd_utils
|
||||
from aprsd.client import client_factory, kiss
|
||||
from aprsd.main import cli
|
||||
from aprsd.threads import aprsd as aprsd_threads
|
||||
from aprsd.threads import keep_alive, rx, tx
|
||||
from aprsd.threads import keep_alive, rx
|
||||
from aprsd.threads import stats as stats_thread
|
||||
from aprsd.threads import tx
|
||||
from aprsd.utils import trace
|
||||
|
||||
|
||||
@ -614,10 +616,24 @@ def webchat(ctx, flush, port):
|
||||
LOG.error("APRS client is not properly configured in config file.")
|
||||
sys.exit(-1)
|
||||
|
||||
# Creates the client object
|
||||
LOG.info("Creating client connection")
|
||||
aprs_client = client_factory.create()
|
||||
LOG.info(aprs_client)
|
||||
if not aprs_client.login_success:
|
||||
# We failed to login, will just quit!
|
||||
msg = f"Login Failure: {aprs_client.login_failure}"
|
||||
LOG.error(msg)
|
||||
print(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
keepalive = keep_alive.KeepAliveThread()
|
||||
LOG.info("Start KeepAliveThread")
|
||||
keepalive.start()
|
||||
|
||||
stats_store_thread = stats_thread.APRSDStatsStoreThread()
|
||||
stats_store_thread.start()
|
||||
|
||||
socketio = init_flask(loglevel, quiet)
|
||||
rx_thread = rx.APRSDPluginRXThread(
|
||||
packet_queue=threads.packet_queue,
|
||||
|
@ -5,6 +5,7 @@ import tracemalloc
|
||||
|
||||
from loguru import logger
|
||||
from oslo_config import cfg
|
||||
import timeago
|
||||
|
||||
from aprsd import packets, utils
|
||||
from aprsd.client import client_factory
|
||||
@ -98,6 +99,9 @@ class KeepAliveThread(APRSDThread):
|
||||
|
||||
# check the APRS connection
|
||||
cl = client_factory.create()
|
||||
cl_stats = cl.stats()
|
||||
keepalive = timeago.format(cl_stats.get("keepalive", None))
|
||||
LOGU.opt(colors=True).info(f"<green>Client keepalive {keepalive}</green>")
|
||||
# Reset the connection if it's dead and this isn't our
|
||||
# First time through the loop.
|
||||
# The first time through the loop can happen at startup where
|
||||
|
@ -18,6 +18,8 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
|
||||
class APRSDRXThread(APRSDThread):
|
||||
_client = None
|
||||
|
||||
def __init__(self, packet_queue):
|
||||
super().__init__("RX_PKT")
|
||||
self.packet_queue = packet_queue
|
||||
@ -33,6 +35,12 @@ class APRSDRXThread(APRSDThread):
|
||||
self._client = client_factory.create()
|
||||
time.sleep(1)
|
||||
return True
|
||||
|
||||
if not self._client.is_connected:
|
||||
self._client = client_factory.create()
|
||||
time.sleep(1)
|
||||
return True
|
||||
|
||||
# setup the consumer of messages and block until a messages
|
||||
try:
|
||||
# This will register a packet consumer with aprslib
|
||||
|
Loading…
Reference in New Issue
Block a user