Passed
Pull Request — master (#1030)
by Konstantin
02:43
created

ocrd_network.runtime_data   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 124
Duplicated Lines 20.16 %

Importance

Changes 0
Metric Value
wmc 24
eloc 94
dl 25
loc 124
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
F DataHost.__init__() 0 41 14
A DataProcessingWorker.__init__() 0 6 1
A DataMongoDB.__init__() 11 11 1
A DataProcessorServer.__init__() 0 7 1
A DataRabbitMQ.__init__() 12 12 1
B DataHost.create_client() 0 14 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
from __future__ import annotations
2
from typing import Dict, List
3
4
from .deployment_utils import (
5
    create_docker_client,
6
    create_ssh_client,
7
    DeployType
8
)
9
10
__all__ = [
11
    'DataHost',
12
    'DataMongoDB',
13
    'DataProcessingWorker',
14
    'DataProcessorServer',
15
    'DataRabbitMQ'
16
]
17
18
19
class DataHost:
20
    def __init__(self, config: Dict) -> None:
21
        self.address = config['address']
22
        self.username = config['username']
23
        self.password = config.get('password', None)
24
        self.keypath = config.get('path_to_privkey', None)
25
26
        # These flags are used to track whether a connection
27
        # of the specified type will be required
28
        self.needs_ssh: bool = False
29
        self.needs_docker: bool = False
30
31
        self.ssh_client = None
32
        self.docker_client = None
33
34
        # TODO: Not sure this is DS is ideal, seems off
35
        self.data_workers: List[DataProcessingWorker] = []
36
        self.data_servers: List[DataProcessorServer] = []
37
38
        for worker in config.get('workers', []):
39
            name = worker['name']
40
            count = worker['number_of_instance']
41
            deploy_type = DeployType.DOCKER if worker.get('deploy_type', None) == 'docker' else DeployType.NATIVE
42
            if not self.needs_ssh and deploy_type == DeployType.NATIVE:
43
                self.needs_ssh = True
44
            if not self.needs_docker and deploy_type == DeployType.DOCKER:
45
                self.needs_docker = True
46
            for _ in range(count):
47
                self.data_workers.append(DataProcessingWorker(self.address, deploy_type, name))
48
49
        for server in config.get('servers', []):
50
            name = server['name']
51
            port = server['port']
52
            deploy_type = DeployType.DOCKER if server.get('deploy_type', None) == 'docker' else DeployType.NATIVE
53
            if not self.needs_ssh and deploy_type == DeployType.NATIVE:
54
                self.needs_ssh = True
55
            if not self.needs_docker and deploy_type == DeployType.DOCKER:
56
                self.needs_docker = True
57
            self.data_servers.append(DataProcessorServer(self.address, port, deploy_type, name))
58
59
        # Key: processor_name, Value: list of ports
60
        self.server_ports: dict = {}
61
62
    def create_client(self, client_type: str):
63
        if client_type not in ['docker', 'ssh']:
64
            raise ValueError(f'Host client type cannot be of type: {client_type}')
65
        if client_type == 'ssh':
66
            if not self.ssh_client:
67
                self.ssh_client = create_ssh_client(
68
                    self.address, self.username, self.password, self.keypath)
69
            return self.ssh_client
70
        if client_type == 'docker':
71
            if not self.docker_client:
72
                self.docker_client = create_docker_client(
73
                    self.address, self.username, self.password, self.keypath
74
                )
75
            return self.docker_client
76
77
78
class DataProcessingWorker:
79
    def __init__(self, host: str, deploy_type: DeployType, processor_name: str) -> None:
80
        self.host = host
81
        self.deploy_type = deploy_type
82
        self.processor_name = processor_name
83
        # Assigned when deployed
84
        self.pid = None
85
86
87
class DataProcessorServer:
88
    def __init__(self, host: str, port: int, deploy_type: DeployType, processor_name: str) -> None:
89
        self.host = host
90
        self.port = port
91
        self.deploy_type = deploy_type
92
        self.processor_name = processor_name
93
        # Assigned when deployed
94
        self.pid = None
95
96
97 View Code Duplication
class DataMongoDB:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
98
    def __init__(self, config: Dict) -> None:
99
        self.address = config['address']
100
        self.port = int(config['port'])
101
        self.ssh_username = config['ssh']['username']
102
        self.ssh_keypath = config['ssh'].get('path_to_privkey', None)
103
        self.ssh_password = config['ssh'].get('password', None)
104
        self.username = config['credentials']['username']
105
        self.password = config['credentials']['password']
106
        self.url = f'mongodb://{self.address}:{self.port}'
107
        # Assigned when deployed
108
        self.pid = None
109
110
111 View Code Duplication
class DataRabbitMQ:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
112
    def __init__(self, config: Dict) -> None:
113
        self.address = config['address']
114
        self.port = int(config['port'])
115
        self.ssh_username = config['ssh']['username']
116
        self.ssh_keypath = config['ssh'].get('path_to_privkey', None)
117
        self.ssh_password = config['ssh'].get('password', None)
118
        self.vhost = '/'
119
        self.username = config['credentials']['username']
120
        self.password = config['credentials']['password']
121
        self.url = f'amqp://{self.username}:{self.password}@{self.address}:{self.port}{self.vhost}'
122
        # Assigned when deployed
123
        self.pid = None
124