Esempio n. 1
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("Ropu Load Balancer");
            Console.WriteLine("Copyright (c) Daniel Hughes");
            Console.WriteLine();

            var settingsReader = new CommandLineSettingsReader();
            var settings       = settingsReader.ParseArgs(args);

            if (settings == null)
            {
                return;
            }

            var credentialsProvider = new CredentialsProvider()
            {
                Email    = settings.Email,
                Password = settings.Password
            };
            var webClient    = new RopuWebClient("https://192.168.1.9:5001/", credentialsProvider);
            var groupsClient = new GroupsClient(webClient, new ImageClient(webClient));


            var keysClient           = new KeysClient(webClient, true, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key)));
            var packetEncryption     = new PacketEncryption(keysClient);
            var loadBalancerProtocol = new LoadBalancerProtocol(new PortFinder(), 5069, packetEncryption, keysClient);

            var servicesClient = new ServicesClient(webClient, ServiceType.LoadBalancer);

            var controller = new LoadBalancerRunner(keysClient, loadBalancerProtocol, groupsClient, webClient, settings, servicesClient);
            await controller.Run();
        }
Esempio n. 2
0
 public LoginViewModel(
     INavigator navigator,
     RopuWebClient webClient,
     ISettingsManager settingsManager)
 {
     _navigator       = navigator;
     _webClient       = webClient;
     _settingsManager = settingsManager;
 }
Esempio n. 3
0
        public void Run(string[] args)
        {
            var settingsReader = new CommandLineClientSettingsReader();

            if (!settingsReader.ParseArgs(args))
            {
                return;
            }

            var settings = settingsReader.ClientSettings;

            if (settings.Email == null)
            {
                Console.Error.WriteLine("No Email configured");
                return;
            }

            if (settings.Password == null)
            {
                Console.Error.WriteLine("No Password configured");
                return;
            }

            var credentials = new CredentialsProvider()
            {
                Email    = settings.Email,
                Password = settings.Password
            };

            var webClient = new RopuWebClient("asdf", credentials);


            var keysClient       = new KeysClient(webClient, false, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key)));
            var packetEncryption = new PacketEncryption(keysClient);

            var protocolSwitch    = new ProtocolSwitch(_controlPortStarting, new PortFinder(), packetEncryption, keysClient, settings);
            var servingNodeClient = new ServingNodeClient(protocolSwitch);

            var callManagementProtocol = new LoadBalancerProtocol(new PortFinder(), 5079, packetEncryption, keysClient);

            _mediaClient = BuildMediaClient(protocolSwitch, settings);

            //IPEndPoint loadBalancerEndpoint = new IPEndPoint(settings.LoadBalancerIPAddress, LoadBalancerPort);
            var beepPlayer = BuildBeepPlayer(settings);



            _ropuClient = new RopuClient(protocolSwitch, servingNodeClient, _mediaClient, callManagementProtocol, settings, beepPlayer, webClient, keysClient);
            var ropuClientTask = _ropuClient.Run();

            //var consoleTask = TaskCordinator.RunLong(HandleCommands);

            //TaskCordinator.WaitAll(ropuClientTask, consoleTask).Wait();
            ropuClientTask.Wait();
        }
Esempio n. 4
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("Ropu Serving Node");
            Console.WriteLine("Copyright (c) Daniel Hughes");
            Console.WriteLine();

            var settingsReader = new CommandLineSettingsReader();
            var settings       = settingsReader.ParseArgs(args);

            if (settings == null)
            {
                return;
            }

            var portFinder          = new PortFinder();
            var credentialsProvider = new CredentialsProvider()
            {
                Email    = settings.Email,
                Password = settings.Password
            };
            var webClient        = new RopuWebClient("https://192.168.1.9:5001", credentialsProvider);
            var keysClient       = new KeysClient(webClient, true, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key)));
            var packetEncryption = new PacketEncryption(keysClient);

            var mediaProtocol        = new RopuProtocol(portFinder, StartingServingNodePort, packetEncryption, keysClient);
            var loadBalancerProtocol = new LoadBalancerProtocol(portFinder, StartingLoadBalancerPort, packetEncryption, keysClient);
            var serviceDiscovery     = new ServiceDiscovery();

            var groupsClient = new GroupsClient(webClient, new ImageClient(webClient));
            var registra     = new Registra(groupsClient);
            var servingNodes = new ServingNodes(100);
            var groupCallControllerLookup = new GroupCallControllerLookup();

            var servicesClient = new ServicesClient(webClient, ServiceType.ServingNode);

            var servingNodeRunner = new ServingNodeRunner(
                mediaProtocol,
                loadBalancerProtocol,
                serviceDiscovery,
                registra,
                servingNodes,
                groupCallControllerLookup,
                servicesClient,
                keysClient);

            await servingNodeRunner.Run();
        }
Esempio n. 5
0
        public PttViewModel(
            RopuClient ropuClient,
            ISettingsManager settingsManager,
            IGroupsClient groupsClient,
            IUsersClient usersClient,
            ImageClient imageClient,
            IColorService <ColorT> colorService,
            Action <Func <Task> > invoke,
            IPermissionService permissionService,
            RopuWebClient webClient,
            INavigator navigator)
        {
            _navigator  = navigator;
            _ropuClient = ropuClient;
            _webClient  = webClient;

            _ropuClient.StateChanged += (sender, args) =>
            {
                invoke(ChangeState);
            };
            _ropuClient.IdleGroupChanged += async(sender, args) =>
            {
                await UpdateIdleGroup();
                await ChangeState();
            };
            _groupsClient = groupsClient;
            _usersClient  = usersClient;
            _imageClient  = imageClient;

            _settingsManager   = settingsManager;
            _colorService      = colorService;
            _permissionService = permissionService;

            Blue  = _colorService.FromRgb(0x3193e3);
            Green = _colorService.FromRgb(0x31e393);
            Gray  = _colorService.FromRgb(0x999999);
            Red   = _colorService.FromRgb(0xFF6961);

            _pttColor          = Gray;
            _receivingColor    = Red;
            _transmittingColor = Green;

            _state = _ropuClient.State.ToString();
        }
Esempio n. 6
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("Starting Ropu Call Controller");
            Console.WriteLine("Copyright (c) Daniel Hughes 2018");
            Console.WriteLine();

            var settingsReader = new CommandLineSettingsReader();
            var settings       = settingsReader.ParseArgs(args);

            if (settings == null)
            {
                return;
            }

            var credentialsProvider = new CredentialsProvider()
            {
                Email    = settings.Email,
                Password = settings.Password
            };
            var webClient = new RopuWebClient("https://192.168.1.9:5001", credentialsProvider);

            var portFinder           = new PortFinder();
            var keysClient           = new KeysClient(webClient, true, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key)));
            var packetEncryption     = new PacketEncryption(keysClient);
            var ropuProtocol         = new RopuProtocol(portFinder, 9000, packetEncryption);
            var loadBalancerProtocol = new LoadBalancerProtocol(portFinder, StartingControlPort, packetEncryption, keysClient);
            var serviceDiscovery     = new ServiceDiscovery();
            var servingNodes         = new ServingNodes(100);


            var servicesClient = new ServicesClient(webClient, ServiceType.CallController);

            var callControl = new CallControl(
                loadBalancerProtocol,
                serviceDiscovery,
                ropuProtocol,
                servingNodes,
                servicesClient,
                keysClient);

            await callControl.Run();
        }
Esempio n. 7
0
        public LoadBalancerRunner(
            KeysClient keysClient,
            LoadBalancerProtocol loadBalancerProtocol,
            IGroupsClient groupsClient,
            RopuWebClient webClient,
            CommandLineSettings settings,
            ServicesClient servicesClient)
        {
            _keysClient           = keysClient;
            _settings             = settings;
            _loadBalancerProtocol = loadBalancerProtocol;
            _loadBalancerProtocol.SetServerMessageHandler(this);
            _groupsClient   = groupsClient;
            _webClient      = webClient;
            _servicesClient = servicesClient;

            _servingNodes = new ControllerRegistry <RegisteredServingNode>();

            _callControllers = new CallControllerRegistry(groupsClient);
            _callControllers.SetGroupCallControllerListener(this);
        }
Esempio n. 8
0
        static void Main(string[] args)
        {
            const ushort controlPortStarting = 5061;

            var settingsManager = new CommandLineClientSettingsReader();

            if (!settingsManager.ParseArgs(args))
            {
                return;
            }

            var settings = settingsManager.ClientSettings;

            var webClient = new RopuWebClient("https://192.168.1.9:5001/", settingsManager);

            var keysClient       = new KeysClient(webClient, false, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key)));
            var packetEncryption = new PacketEncryption(keysClient);

            var protocolSwitch    = new ProtocolSwitch(controlPortStarting, new PortFinder(), packetEncryption, keysClient, settings);
            var servingNodeClient = new ServingNodeClient(protocolSwitch);

            IAudioSource audioSource =
                settings.FileMediaSource != null ?
                (IAudioSource) new FileAudioSource(settings.FileMediaSource) :
                (IAudioSource) new PulseAudioSimple(StreamDirection.Record, "RopuInput");

            var audioPlayer            = new PulseAudioSimple(StreamDirection.Playback, "RopuOutput");
            var audioCodec             = new OpusCodec();
            var jitterBuffer           = new AdaptiveJitterBuffer(2, 50);
            var mediaClient            = new MediaClient(protocolSwitch, audioSource, audioPlayer, audioCodec, jitterBuffer, settings);
            var callManagementProtocol = new LoadBalancerProtocol(new PortFinder(), 5079, packetEncryption, keysClient);

            var beepPlayer = new BeepPlayer(new PulseAudioSimple(StreamDirection.Playback, "RopuBeeps"));


            var ropuClient = new RopuClient(protocolSwitch, servingNodeClient, mediaClient, callManagementProtocol, settings, beepPlayer, webClient, keysClient);

            var application = new RopuApplication(ropuClient);

            var imageService = new ImageService();

            //TODO: get web address from config
            var imageClient  = new ImageClient(webClient);
            var groupsClient = new GroupsClient(webClient, imageClient);
            var usersClient  = new UsersClient(webClient);
            //settings.UserId = usersClient.GetCurrentUser().Result.Id;
            var pttPage = new PttPage(imageService);

            var navigator = new Navigator();

            var colorService = new ColorService();

            navigator.Register <LoginViewModel, LoginView>(() => new LoginView(new LoginViewModel(navigator, webClient, settingsManager), imageService));

            navigator.Register <SignupViewModel, SignupPage>(() => new SignupPage(new SignupViewModel(navigator, usersClient), imageService));

            Action <Func <Task> > invoke = toDo => Application.Instance.Invoke(toDo);

            var permissionServices = new PermissionServices();

            var pttView = new PttView(new PttViewModel <Color>(ropuClient, settingsManager, groupsClient, usersClient, imageClient, colorService, invoke, permissionServices, webClient, navigator), pttPage);

            navigator.Register <PttViewModel <Color>, PttView>(() => pttView);
            navigator.RegisterView("HomeRightPanel", "PttView", () => pttView);


            var homeView = new HomeView(new HomeViewModel(navigator), navigator, colorService);

            navigator.Register <HomeViewModel, HomeView>(() => homeView);

            var browseGroupsView = new BrowseGroupsView(new BrowseGroupsViewModel(groupsClient, navigator));

            navigator.Register <BrowseGroupsViewModel, BrowseGroupsView>(() => browseGroupsView);

            Func <Group, BrowseGroupView> browseGroupViewBuilder = group => new BrowseGroupView(new BrowseGroupViewModel(group, groupsClient, settings, navigator), imageService, navigator, colorService);

            navigator.Register <BrowseGroupViewModel, BrowseGroupView, Group>(group => browseGroupViewBuilder(group));

            var selectIdleGroupView = new SelectIdleGroupView(new SelectGroupViewModel(groupsClient, navigator, ropuClient));

            navigator.RegisterView("HomeRightPanel", "SelectIdleGroupView", () => selectIdleGroupView);

            var mainForm = new MainView(navigator, new MainViewModel(settings, navigator));

            mainForm.Icon = imageService.Ropu;

            var ignore = navigator.ShowModal <HomeViewModel>();

            ignore = navigator.ShowPttView();
            application.Run(mainForm);
        }
Esempio n. 9
0
 public UsersClient(RopuWebClient client)
 {
     _client = client;
 }
Esempio n. 10
0
        public RopuClient(
            ProtocolSwitch protocolSwitch,
            ServingNodeClient servingNodeClient,
            IMediaClient mediaClient,
            LoadBalancerProtocol loadBalancerProtocol,
            IClientSettings clientSettings,
            IBeepPlayer beepPlayer,
            RopuWebClient webClient,
            KeysClient keysClient)
        {
            _webClient            = webClient;
            _beepPlayer           = beepPlayer;
            _clientSettings       = clientSettings;
            _loadBalancerProtocol = loadBalancerProtocol;
            _protocolSwitch       = protocolSwitch;
            _servingNodeClient    = servingNodeClient;
            _mediaClient          = mediaClient;
            _servingNodeClient.SetControllingFunctionHandler(this);
            _retryTimer = new Ropu.Shared.Timer();
            _keysClient = keysClient;

            var allEvents = (EventId[])Enum.GetValues(typeof(EventId));

            //start
            _start        = new RopuState(StateId.Start);
            _stateManager = new StateManager <StateId, EventId>(_start);
            _stateManager.AddState(_start);
            _start.AddTransitions(allEvents, () => _start);

            //registered
            _registered = new RopuState(StateId.Registered)
            {
                Entry = async token =>
                {
                    if (_clientSettings.UserId == null)
                    {
                        throw new InvalidOperationException("UserId is not set");
                    }
                    _callGroup        = IdleGroup;
                    _registeredUserId = _clientSettings.UserId.Value;
                    if (_heartbeatTask == null)
                    {
                        _heartbeatTask = Heartbeat(_heartbeatCancellationTokenSource.Token);
                    }
                    _heartbeatOnEvent.Set(); //allows the heartbeat to continue
                    await Task.Run(() => {});
                },
            };
            _stateManager.AddState(_registered);
            _registered.AddTransition(EventId.CallRequest, () => _startingCall !);
            _registered.AddTransition(EventId.PttDown, () => _startingCall !);
            _registered.AddTransition(EventId.RegistrationResponseReceived, () => _registered);
            _registered.AddTransition(EventId.CallStartFailed, () => _registered);
            _registered.AddTransition(EventId.PttUp, () => _registered);
            _registered.AddTransition(EventId.GroupSelected, () => _registered);

            //unregistered
            _noGroup      = new RopuState(StateId.NoGroup);
            _unregistered = new RopuState(StateId.Unregistered)
            {
                Entry = async token =>
                {
                    _heartbeatOnEvent.Reset(); //stops the heartbeat
                    await Register(token);
                }
            };
            _unregistered.AddTransition(EventId.RegistrationResponseReceived, () => IdleGroup == null ? _noGroup : _registered);
            _unregistered.AddTransition(EventId.FloorIdle, () => _unregistered);
            _unregistered.AddTransition(EventId.FloorTaken, () => _unregistered);
            _unregistered.AddTransition(EventId.CallEnded, () => _unregistered);
            _unregistered.AddTransition(EventId.CallRequest, () => _unregistered);
            _unregistered.AddTransition(EventId.CallStartFailed, () => _unregistered);
            _unregistered.AddTransition(EventId.HeartbeatFailed, () => _unregistered);
            _unregistered.AddTransition(EventId.PttUp, () => _unregistered);
            _unregistered.AddTransition(EventId.PttDown, () => _unregistered);
            _unregistered.AddTransition(EventId.GroupSelected, () => _unregistered);

            _stateManager.AddState(_unregistered);

            //no group
            _noGroup.AddTransition(EventId.PttUp, () => _noGroup);
            _noGroup.AddTransition(EventId.PttDown, () => _noGroup);
            _noGroup.AddTransition(EventId.GroupSelected, () => _registered);
            _noGroup.AddTransition(EventId.RegistrationResponseReceived, () => _noGroup);
            _noGroup.AddTransition(EventId.CallRequest, () => _noGroup);
            _noGroup.AddTransition(EventId.CallStartFailed, () => _noGroup);


            _stateManager.AddState(_noGroup);

            //deregistering
            _deregistering = new RopuState(StateId.Deregistering)
            {
                Entry = async token => await Deregister(token),
            };
            _deregistering.AddTransition(EventId.DeregistrationResponseReceived, () => _unregistered);
            _deregistering.AddTransitions(allEvents.Where(e => e != EventId.DeregistrationResponseReceived), () => _deregistering);
            _deregistering.AddTransition(EventId.GroupSelected, () => _deregistering);
            _stateManager.AddState(_deregistering);

            //starting call
            _startingCall = new RopuState(StateId.StartingCall)
            {
                Entry = async token => await StartCall(token),
                Exit  = newState =>
                {
                    if (newState != _inCallTransmitting && newState != _inCallRequestingFloor)
                    {
                        _mediaClient.StopSendingAudio();
                    }
                }
            };
            _startingCall.AddTransition(EventId.CallStartFailed, () => _registered);
            _startingCall.AddTransition(EventId.PttUp, () => _startingCall);
            _startingCall.AddTransition(EventId.PttDown, () => _startingCall);
            _startingCall.AddTransition(EventId.RegistrationResponseReceived, () => _startingCall);
            _startingCall.AddTransition(EventId.CallRequest, () => _startingCall);
            _startingCall.AddTransition(EventId.GroupSelected, () => _startingCall);

            _stateManager.AddState(_startingCall);

            //in call idle
            _inCallIdle = new RopuState(StateId.InCallIdle);
            _inCallIdle.AddTransition(EventId.PttDown, () => _inCallRequestingFloor !);
            _inCallIdle.AddTransition(EventId.PttUp, () => _inCallIdle);
            _inCallIdle.AddTransition(EventId.RegistrationResponseReceived, () => _inCallIdle);
            _inCallIdle.AddTransition(EventId.CallRequest, () => _inCallIdle);
            _inCallIdle.AddTransition(EventId.CallStartFailed, () => _registered);
            _inCallIdle.AddTransition(EventId.GroupSelected, () => _inCallIdle);
            _stateManager.AddState(_inCallIdle);

            //in call receiving
            _inCallReceiveing = new RopuState(StateId.InCallReceiving);
            _inCallReceiveing.AddTransition(EventId.PttDown, () => _inCallReceiveing);
            _inCallReceiveing.AddTransition(EventId.PttUp, () => _inCallReceiveing);
            _inCallReceiveing.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReceiveing);
            _inCallReceiveing.AddTransition(EventId.CallRequest, () => _inCallReceiveing);
            _inCallReceiveing.AddTransition(EventId.CallStartFailed, () => _registered);
            _inCallReceiveing.AddTransition(EventId.GroupSelected, () => _inCallReceiveing);
            _stateManager.AddState(_inCallReceiveing);

            //in call transmitting
            _inCallTransmitting = new RopuState(StateId.InCallTransmitting)
            {
                Entry = async token =>
                {
                    _beepPlayer.PlayGoAhead();
                    await Task.Run(() => {});
                },
                Exit = newState =>
                {
                    if (newState != _inCallTransmitting && newState != _inCallRequestingFloor)
                    {
                        _mediaClient.StopSendingAudio();
                    }
                }
            };
            _inCallTransmitting.AddTransition(EventId.PttUp, () => _inCallReleasingFloor !);
            _inCallTransmitting.AddTransition(EventId.RegistrationResponseReceived, () => _inCallTransmitting);
            _inCallTransmitting.AddTransition(EventId.CallRequest, () => _inCallTransmitting);
            _inCallTransmitting.AddTransition(EventId.CallStartFailed, () => _inCallTransmitting);
            _inCallTransmitting.AddTransition(EventId.PttDown, () => _inCallTransmitting);
            _inCallTransmitting.AddTransition(EventId.GroupSelected, () => _inCallTransmitting);

            _stateManager.AddState(_inCallTransmitting);

            //in call requesting floor
            _inCallRequestingFloor = new RopuState(StateId.InCallRequestingFloor)
            {
                Entry = token =>
                {
                    if (_callGroup == null)
                    {
                        return(Task.CompletedTask);
                    }
                    if (_clientSettings.UserId == null)
                    {
                        throw new InvalidOperationException("UserId is not set");
                    }
                    _servingNodeClient.SendFloorRequest(_callGroup.Value, _clientSettings.UserId.Value);
                    StartSendingAudio();
                    return(Task.CompletedTask);
                },
                Exit = newState =>
                {
                    if (newState != _inCallTransmitting && newState != _inCallRequestingFloor)
                    {
                        _mediaClient.StopSendingAudio();
                        _beepPlayer.PlayDenied();
                    }
                }
            };
            _inCallRequestingFloor.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReleasingFloor !);
            _inCallRequestingFloor.AddTransition(EventId.CallRequest, () => _inCallReleasingFloor !);
            _inCallRequestingFloor.AddTransition(EventId.CallStartFailed, () => _registered);
            _inCallRequestingFloor.AddTransition(EventId.PttDown, () => _inCallRequestingFloor);
            _inCallRequestingFloor.AddTransition(EventId.PttUp, () => _inCallIdle);
            _inCallRequestingFloor.AddTransition(EventId.GroupSelected, () => _inCallRequestingFloor);
            _stateManager.AddState(_inCallRequestingFloor);

            //in call releasing floor
            _inCallReleasingFloor = new RopuState(StateId.InCallReleasingFloor)
            {
                Entry = async token =>
                {
                    if (_callGroup == null)
                    {
                        throw new InvalidOperationException("No call group");
                    }
                    if (_clientSettings.UserId == null)
                    {
                        throw new InvalidOperationException("UserId is not set");
                    }
                    while (!token.IsCancellationRequested)
                    {
                        _servingNodeClient.SendFloorReleased(_callGroup.Value, _clientSettings.UserId.Value);
                        await Task.Run(() => token.WaitHandle.WaitOne(1000));
                    }
                }
            };
            _inCallReleasingFloor.AddTransition(EventId.FloorGranted, () => _inCallReleasingFloor);
            _inCallReleasingFloor.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReleasingFloor);
            _inCallReleasingFloor.AddTransition(EventId.CallRequest, () => _inCallReleasingFloor);
            _inCallReleasingFloor.AddTransition(EventId.CallStartFailed, () => _registered);
            _inCallReleasingFloor.AddTransition(EventId.PttDown, () => _inCallRequestingFloor);
            _inCallReleasingFloor.AddTransition(EventId.PttUp, () => _inCallReleasingFloor);
            _inCallReleasingFloor.AddTransition(EventId.GroupSelected, () => _inCallReleasingFloor);

            _stateManager.AddState(_inCallReleasingFloor);


            _inCallReleasingFloor.AddTransition(EventId.FloorGranted, () => _inCallReleasingFloor);


            _stateManager.StateChanged += (sender, args) =>
            {
                Console.WriteLine($"State Changed {this._stateManager.CurrentState}");
                StateChanged?.Invoke(this, args);
            };

            _stateManager.AddTransitionToAll(EventId.HeartbeatFailed, () => _unregistered, stateId => true);
            _stateManager.AddTransitionToAll(EventId.NotRegistered, () => _unregistered, stateId => true);
            _stateManager.AddTransitionToAll(EventId.CallEnded, () => _registered, stateId => stateId != StateId.Unregistered && stateId != StateId.Start && stateId != StateId.Deregistering);
            _stateManager.AddTransitionToAll(EventId.FloorIdle, () => _inCallIdle, IsRegistered);
            _stateManager.AddTransitionToAll(EventId.FloorTaken, () => _inCallReceiveing, IsRegistered);
            _stateManager.AddTransitionToAll(EventId.FloorGranted, () => _inCallTransmitting, stateId => stateId != StateId.InCallReleasingFloor);
            _stateManager.AddTransitionToAll(EventId.DeregistrationResponseReceived, () => _unregistered, stateId => true);
            _stateManager.AddTransitionToAll(EventId.GroupDeselected, () => _noGroup, stateId => true);

            _stateManager.CheckEventsAreHandledByAll((EventId[])Enum.GetValues(typeof(EventId)));
        }
Esempio n. 11
0
 public KeysClient(RopuWebClient ropuWebClient, bool cacheAllServices, Func <EncryptionKey, CachedEncryptionKey> cachedEncryiptonKeyFactory)
 {
     _ropuWebClient              = ropuWebClient;
     _cacheAllServices           = cacheAllServices;
     _cachedEncryiptonKeyFactory = cachedEncryiptonKeyFactory;
 }