Files

203 lines
7.2 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module JSON
( P2PRCConfig(..)
, IPAddressTable(..)
, IPAddress(..)
, ServerInfo(..)
, MapPortResponse(..)
)
where
import Control.Monad ( mzero )
import qualified Data.Text as T
import Data.Aeson
{-# WARNING MapPortResponse "This newtype is unstable at the moment due to the P2PRC's library error handling bug. For more information visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114#issuecomment-2474737015" #-}
-- ^ This represents P2PRC's response to the TCP port and DNS address allocation. This value will confirm the successful allocation and return information about it.
newtype MapPortResponse
= MkMapPortResponse -- ^ Allocation information value
String -- ^ Column separated Host's IP address and Port String
deriving Show
instance FromJSON MapPortResponse where
parseJSON (Object o) = do
ipAddress <- o .: "IPAddress"
pure $ MkMapPortResponse ipAddress
parseJSON _ = mzero
{-# WARNING P2PRCConfig "This type is unstable at the moment due to the P2PRC's library error handling bug. For more information visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114#issuecomment-2474737015" #-}
-- | This represents the server configuration that defines its attributes and behaviours in the network, as well as, the location of the runtime persistence artifacts.
newtype P2PRCConfig
= MkP2PRCConfig
{ machineName :: String -- ^ Machine Name
} deriving Show
-- , hostServerPort :: Int
-- , iPV6Address :: Maybe String
-- , proxyPort :: Maybe Int
-- , fRPServerPort :: Bool
-- , behindNAT :: Bool
-- , iPTableKey :: String
-- , bareMetal :: Bool
-- , customConfig :: String
--
-- , iPTable :: String -- File
-- , dockerContainers :: String -- Directory
-- , defaultDockerFile :: String -- Directory
-- , dockerRunLogs :: String -- Directory
-- , speedTestFile :: String -- File
-- , pluginPath :: String -- Directory
-- , trackContainersPath :: String -- File
-- , publicKeyFile :: String -- File
-- , privateKeyFile :: String -- File
-- , pemFile :: String -- File
-- , keyFile :: String -- File
-- , groupTrackContainersPath :: String -- File
-- TODO: p2prc API
--
-- ListServers
-- remove "ip_address" root field if not needed
-- "Nat field" returning a JSON Boolean
-- serverPort as a JSON number
-- baremetalPort as a JSON number
-- have either IPV4 or IPV6 field visible
-- remove "customInformation" if not needed anymore
-- remove "escapeImplementation" if not needed anymore
--
-- Config file
--
-- Fix JSON number: ServerPort
-- Fix: IPV6Address dont show if value does not exist
-- Fix JSON number: ProxyPort to number (dont show if it does not exist)
-- Fix JSON number: fRPServerPort
-- Fix JSON boolean: fRPServerPort
-- Fix JSON boolean: behindNAT
-- Fix JSON boolean: bareMetal
-- remove "customConfig" if not needed
--
-- MapPort
-- to have a dedicated ip address (with type either IPV6 or IPV4 fields)
-- to have a dedicated port field
instance FromJSON P2PRCConfig where
parseJSON (Object o) = do
machineName <- o .: "MachineName"
pure
$ MkP2PRCConfig
{ machineName=machineName
}
parseJSON _ = mzero
{-# WARNING IPAddressTable "This newtype is highly unstable due to undergoing work on improving P2PRC's server api. For more information, visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114" #-}
-- | This is a wrapper value that parses a json key value from the list of ip addresses in the network.
newtype IPAddressTable
= MkIPAddressTable -- ^ Wrapping constructor
[ServerInfo] -- ^ List current network servers
deriving Show
instance FromJSON IPAddressTable where
parseJSON = withObject "IPAdressTable" $
\ v ->
MkIPAddressTable <$> v .: "ip_address"
{-# WARNING ServerInfo "This type is highly unstable due to undergoing work on improving P2PRC's server api. For more information, visit: https://github.com/Akilan1999/p2p-rendering-computation/issues/114" #-}
{- |
This is a record that keeps track of the current state of every node in the network. It is crucial information required for orchestration strategies.
-}
data ServerInfo =
MkServerInfo
{ name :: T.Text -- ^ Machine name
, ip :: IPAddress -- ^ Machine IP address
, latency :: Int -- ^ Response latency
, download :: Int -- ^ Download speed
, upload :: Int -- ^ Upload speed
, serverPort :: Int -- ^ Server port number
, bareMetalSSHPort :: Maybe Int -- ^ SSH machine port number
, nat :: Bool -- ^ Checking if node is behind a NAT
, escapeImplementation :: Maybe T.Text -- ^ Type of NAT trasversal technique
, customInformation :: Maybe T.Text -- ^ Custom String information
}
deriving Show
-- | This is a simple representation of the IP address of nodes in the network.
data IPAddress
= MkIPv4 String -- ^ IP version 4 address
| MkIPv6 String -- ^ IP version 6 address
deriving Show
instance FromJSON ServerInfo where
parseJSON = withObject "ServerInfo" $
\ o -> do
name <- o .: "Name"
ip4str <- o .: "IPV4"
ip6str <- o .: "IPV6"
latency <- o .: "Latency"
download <- o .: "Download"
upload <- o .: "Upload"
serverPort <- o .: "ServerPort"
bmSshPort <- o .: "BareMetalSSHPort"
nat <- o .: "NAT"
mEscImpl <- o .: "EscapeImplementation"
custInfo <- o .: "CustomInformation"
pure $
MkServerInfo
{ name = name
, ip = getIPAddress ip4str ip6str
, latency = latency
, download = download
, upload = upload
, serverPort = getPortUNSAFE serverPort
, bareMetalSSHPort = getBMShhPort bmSshPort
, nat = getNat nat
, escapeImplementation = mEscImpl
, customInformation = custInfo -- TODO: deal with null value
}
where
getNat :: String -> Bool -- TODO: Change it to normal JSON
getNat ('T':_) = True
getNat _ = False
getBMShhPort :: String -> Maybe Int -- TODO: Dangerous partial function call !!!!!!!!!!!!!!!!!!!
getBMShhPort [] = Nothing
getBMShhPort bmSshPort = Just $ getPortUNSAFE bmSshPort
getPortUNSAFE :: String -> Int -- TODO: Dangerous partial function call !!!!!!!!!!!!!!!!!!!
getPortUNSAFE = read
getIPAddress :: String -> String -> IPAddress
getIPAddress [] ip6 = MkIPv6 ip6
getIPAddress ip4 _ = MkIPv4 ip4