diff options
Diffstat (limited to 'src/connection_details.rs')
-rw-r--r-- | src/connection_details.rs | 362 |
1 files changed, 361 insertions, 1 deletions
diff --git a/src/connection_details.rs b/src/connection_details.rs index 03f33f5..1d18bf6 100644 --- a/src/connection_details.rs +++ b/src/connection_details.rs @@ -1,3 +1,363 @@ +use crate::client_listener::ClientListener; +use crate::IllegalArgumentException; + +/// Used by `LightstreamerClient` to provide a basic connection properties data object. +/// +/// Data object that contains the configuration settings needed to connect to a Lightstreamer Server. +/// +/// An instance of this class is attached to every `LightstreamerClient` as `LightstreamerClient.connectionDetails` +/// +/// See also `LightstreamerClient` pub struct ConnectionDetails { + adapter_set: String, + client_ip: Option<String>, + server_address: String, + server_instance_address: Option<String>, + server_socket_name: Option<String>, + session_id: Option<String>, + user: Option<String>, + password: Option<String>, + listeners: Vec<Box<dyn ClientListener>>, +} + +impl ConnectionDetails { + /// Inquiry method that gets the name of the Adapter Set (which defines the Metadata Adapter + /// and one or several Data Adapters) mounted on Lightstreamer Server that supply all the + /// items used in this application. + /// + /// # Returns + /// + /// The name of the Adapter Set; returns `None` if no name has been configured, that means + /// that the "DEFAULT" Adapter Set is used. + /// + /// See also `setAdapterSet()` + pub fn get_adapter_set(&self) -> &String { + self.adapter_set.as_ref() + } + + /// Inquiry method that gets the IP address of this client as seen by the Server which is + /// serving the current session as the client remote address (note that it may not correspond + /// to the client host; for instance it may refer to an intermediate proxy). If, upon a new + /// session, this address changes, it may be a hint that the intermediary network nodes handling + /// the connection have changed, hence the network capabilities may be different. The library + /// uses this information to optimize the connection. + /// + /// Note that in case of polling or in case rebind requests are needed, subsequent requests + /// related to the same session may, in principle, expose a different IP address to the Server; + /// these changes would not be reported. + /// + /// If a session is not currently active, `None` is returned; soon after a session is established, + /// the value may become available; but it is possible that this information is not provided + /// by the Server and that it will never be available. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "clientIp" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Returns + /// + /// A canonical representation of an IP address (it can be either IPv4 or IPv6), or `None`. + pub fn get_client_ip(&self) -> Option<&String> { + self.client_ip.as_ref() + } + + /// Inquiry method that gets the configured address of Lightstreamer Server. + /// + /// # Returns + /// + /// The configured address of Lightstreamer Server. + pub fn get_server_address(&self) -> Option<&String> { + self.server_address.as_ref() + } + + /// Inquiry method that gets the server address to be used to issue all requests related to + /// the current session. In fact, when a Server cluster is in place, the Server address specified + /// through `setServerAddress()` can identify various Server instances; in order to ensure that + /// all requests related to a session are issued to the same Server instance, the Server can + /// answer to the session opening request by providing an address which uniquely identifies + /// its own instance. When this is the case, this address is returned by the method; otherwise, + /// `None` is returned. + /// + /// Note that the addresses will always have the `http:` or `https:` scheme. In case WebSockets + /// are used, the specified scheme is internally converted to match the related WebSocket protocol + /// (i.e. `http` becomes `ws` while `https` becomes `wss`). + /// + /// Server Clustering is an optional feature, available depending on Edition and License Type. + /// To know what features are enabled by your license, please see the License tab of the Monitoring + /// Dashboard (by default, available at /dashboard). + /// + /// The method gives a meaningful answer only when a session is currently active. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "serverInstanceAddress" on any `ClientListener` listening to the related + /// `LightstreamerClient`. + /// + /// # Returns + /// + /// Address used to issue all requests related to the current session. + pub fn get_server_instance_address(&self) -> Option<&String> { + self.server_instance_address.as_ref() + } + + /// Inquiry method that gets the instance name of the Server which is serving the current session. + /// To be more precise, each answering port configured on a Server instance (through a `<http_server>` + /// or `<https_server>` element in the Server configuration file) can be given a different name; + /// the name related to the port to which the session opening request has been issued is returned. + /// + /// Note that each rebind to the same session can, potentially, reach the Server on a port different + /// than the one used for the previous request, depending on the behavior of intermediate nodes. + /// However, the only meaningful case is when a Server cluster is in place and it is configured + /// in such a way that the port used for all `bind_session` requests differs from the port used + /// for the initial `create_session` request. + /// + /// Server Clustering is an optional feature, available depending on Edition and License Type. + /// To know what features are enabled by your license, please see the License tab of the Monitoring + /// Dashboard (by default, available at /dashboard). + /// + /// If a session is not currently active, `None` is returned; soon after a session is established, + /// the value will become available. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "serverSocketName" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Returns + /// + /// Name configured for the Server instance which is managing the current session, or `None`. + pub fn get_server_socket_name(&self) -> Option<&String> { + self.server_socket_name.as_ref() + } + + /// Inquiry method that gets the ID associated by the server to this client session. + /// + /// The method gives a meaningful answer only when a session is currently active. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "sessionId" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Returns + /// + /// ID assigned by the Server to this client session. + pub fn get_session_id(&self) -> Option<&String> { + self.session_id.as_ref() + } + + /// Inquiry method that gets the username to be used for the authentication on Lightstreamer + /// Server when initiating the session. + /// + /// # Returns + /// + /// The username to be used for the authentication on Lightstreamer Server; returns `None` + /// if no user name has been configured. + pub fn get_user(&self) -> Option<&String> { + self.user.as_ref() + } + + /// Creates a new ConnectionDetails object with default values. + pub fn new(server_address: Option<String>, adapter_set: Option<String>) -> ConnectionDetails { + if let Some(server_address) = server_address { + ConnectionDetails { + server_address: Some(server_address), + adapter_set, + ..Default::default() + } + } else { + ConnectionDetails { + adapter_set, + ..Default::default() + } + } + } + + /// Setter method that sets the name of the Adapter Set mounted on Lightstreamer Server to + /// be used to handle all requests in the session. + /// + /// An Adapter Set defines the Metadata Adapter and one or several Data Adapters. It is configured + /// on the server side through an "adapters.xml" file; the name is configured through the "id" + /// attribute in the `<adapters_conf>` element. + /// + /// The default Adapter Set, configured as "DEFAULT" on the Server. + /// + /// The Adapter Set name should be set on the `LightstreamerClient.connectionDetails` object + /// before calling the `LightstreamerClient.connect()` method. However, the value can be changed + /// at any time: the supplied value will be used for the next time a new session is requested + /// to the server. + /// + /// This setting can also be specified in the `LightstreamerClient` constructor. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "adapterSet" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Parameters + /// + /// * `adapter_set`: The name of the Adapter Set to be used. A `None` value is equivalent to + /// the "DEFAULT" name. + pub fn set_adapter_set(&mut self, adapter_set: Option<String>) { + self.adapter_set = adapter_set; + + // Notify listeners about the property change + for listener in &self.listeners { + listener.on_property_change("adapterSet"); + } + } + + /// Setter method that sets the password to be used for the authentication on Lightstreamer + /// Server when initiating the session. The Metadata Adapter is responsible for checking the + /// credentials (username and password). + /// + /// If no password is supplied, no password information will be sent at session initiation. + /// The Metadata Adapter, however, may still allow the session. + /// + /// The password should be set on the `LightstreamerClient.connectionDetails` object before + /// calling the `LightstreamerClient.connect()` method. However, the value can be changed at + /// any time: the supplied value will be used for the next time a new session is requested to + /// the server. + /// + /// NOTE: The password string will be stored in the current instance. That is necessary in order + /// to allow automatic reconnection/reauthentication for fail-over. For maximum security, avoid + /// using an actual private password to authenticate on Lightstreamer Server; rather use a session-id + /// originated by your web/application server, that can be checked by your Metadata Adapter. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "password" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Parameters + /// + /// * `password`: The password to be used for the authentication on Lightstreamer Server. The + /// password can be `None`. + /// + /// See also `setUser()` + pub fn set_password(&mut self, password: Option<String>) { + self.password = password; + + // Notify listeners about the property change + for listener in &self.listeners { + listener.on_property_change("password"); + } + } + + /// Setter method that sets the address of Lightstreamer Server. + /// + /// Note that the addresses specified must always have the `http:` or `https:` scheme. In case + /// WebSockets are used, the specified scheme is internally converted to match the related WebSocket + /// protocol (i.e. `http` becomes `ws` while `https` becomes `wss`). + /// + /// WSS/HTTPS is an optional feature, available depending on Edition and License Type. To know + /// what features are enabled by your license, please see the License tab of the Monitoring + /// Dashboard (by default, available at /dashboard). + /// + /// If no server address is supplied the client will be unable to connect. + /// + /// This method can be called at any time. If called while connected, it will be applied when + /// the next session creation request is issued. This setting can also be specified in the + /// `LightstreamerClient` constructor. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "serverAddress" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Parameters + /// + /// * `server_address`: The full address of Lightstreamer Server. A `None` value can also be + /// used, to restore the default value. + /// + /// An IPv4 or IPv6 can also be used in place of a hostname. Some examples of valid values include: + /// + /// - `http://push.mycompany.com` + /// - `http://push.mycompany.com:8080` + /// - `http://79.125.7.252` + /// - `http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]` + /// - `http://[2001:0db8:85a3::8a2e:0370:7334]:8080` + /// + /// # Raises + /// + /// * `IllegalArgumentException`: if the given address is not valid. + pub fn set_server_address( + &mut self, + server_address: Option<String>, + ) -> Result<(), IllegalArgumentException> { + // Validate the server address + if let Some(address) = &server_address { + if !address.starts_with("http://") && !address.starts_with("https://") { + return Err(IllegalArgumentException::new( + "Invalid server address: must start with http:// or https://", + )); + } + } + + self.server_address = server_address; + + // Notify listeners about the property change + for listener in &self.listeners { + listener.on_property_change("serverAddress"); + } + + Ok(()) + } + + /// Setter method that sets the username to be used for the authentication on Lightstreamer + /// Server when initiating the session. The Metadata Adapter is responsible for checking the + /// credentials (username and password). + /// + /// If no username is supplied, no user information will be sent at session initiation. The + /// Metadata Adapter, however, may still allow the session. + /// + /// The username should be set on the `LightstreamerClient.connectionDetails` object before + /// calling the `LightstreamerClient.connect()` method. However, the value can be changed at + /// any time: the supplied value will be used for the next time a new session is requested to + /// the server. + /// + /// A change to this setting will be notified through a call to `ClientListener.onPropertyChange()` + /// with argument "user" on any `ClientListener` listening to the related `LightstreamerClient`. + /// + /// # Parameters + /// + /// * `user`: The username to be used for the authentication on Lightstreamer Server. The username + /// can be `None`. + /// + /// See also `setPassword()` + pub fn set_user(&mut self, user: Option<String>) { + self.user = user; + + // Notify listeners about the property change + for listener in &self.listeners { + listener.on_property_change("user"); + } + } + + /// Adds a listener that will receive events related to changes in the `ConnectionDetails`. + /// + /// The same listener can be added to multiple instances of `ConnectionDetails`. + /// + /// # Parameters + /// + /// * `listener`: An object that will receive the events as documented in the `ClientListener` + /// interface. + pub fn add_listener(&mut self, listener: Box<dyn ClientListener>) { + self.listeners.push(listener); + } + + /// Removes a listener from the `ConnectionDetails` instance so that it will not receive events + /// anymore. + /// + /// # Parameters + /// + /// * `listener`: The listener to be removed. + pub fn remove_listener(&mut self, listener: Box<dyn ClientListener>) { + unimplemented!("Implement mechanism to remove listener from ConnectionDetails."); + //self.listeners.remove(&listener); + } +} -}
\ No newline at end of file +impl Default for ConnectionDetails { + fn default() -> Self { + ConnectionDetails { + adapter_set: None, + client_ip: None, + server_address: None, + server_instance_address: None, + server_socket_name: None, + session_id: None, + user: None, + password: None, + listeners: Vec::new(), + } + } +} |