1 | import axios from 'axios';
|
2 | import { fs } from 'appium-support';
|
3 | import logger from './logger';
|
4 | import _ from 'lodash';
|
5 |
|
6 |
|
7 | const hubUri = (config) => {
|
8 | const protocol = config.hubProtocol || 'http';
|
9 | return `${protocol}://${config.hubHost}:${config.hubPort}`;
|
10 | };
|
11 |
|
12 | async function registerNode (configFile, addr, port) {
|
13 | let data;
|
14 | try {
|
15 | data = await fs.readFile(configFile, 'utf-8');
|
16 | } catch (err) {
|
17 | logger.error(`Unable to load node configuration file to register with grid: ${err.message}`);
|
18 | return;
|
19 | }
|
20 |
|
21 |
|
22 | if (!data) {
|
23 | logger.error('No data found in the node configuration file to send to the grid');
|
24 | return;
|
25 | }
|
26 | postRequest(data, addr, port);
|
27 | }
|
28 |
|
29 | async function registerToGrid (postOptions, configHolder) {
|
30 | try {
|
31 | const {status} = await axios(postOptions);
|
32 | if (status !== 200) {
|
33 | throw new Error(`Request failed with code ${status}`);
|
34 | }
|
35 | logger.debug(`Appium successfully registered with the the grid on ` +
|
36 | hubUri(configHolder.configuration));
|
37 | } catch (err) {
|
38 | logger.error(`An attempt to register with the grid was unsuccessful: ${err.message}`);
|
39 | }
|
40 | }
|
41 |
|
42 | function postRequest (data, addr, port) {
|
43 |
|
44 | let configHolder;
|
45 | try {
|
46 | configHolder = JSON.parse(data);
|
47 | } catch (err) {
|
48 | logger.errorAndThrow(`Syntax error in node configuration file: ${err.message}`);
|
49 | }
|
50 |
|
51 |
|
52 | if (!_.has(configHolder, 'configuration')) {
|
53 | let configuration = {};
|
54 | for (const property in configHolder) {
|
55 | if (_.has(configHolder, property) && property !== 'capabilities') {
|
56 | configuration[property] = configHolder[property];
|
57 | delete configHolder[property];
|
58 | }
|
59 | }
|
60 | configHolder.configuration = configuration;
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | if (!configHolder.configuration.url || !configHolder.configuration.host || !configHolder.configuration.port) {
|
69 | configHolder.configuration.url = `http://${addr}:${port}/wd/hub`;
|
70 | configHolder.configuration.host = addr;
|
71 | configHolder.configuration.port = port;
|
72 | }
|
73 |
|
74 | if (!configHolder.configuration.id) {
|
75 | configHolder.configuration.id = `http://${configHolder.configuration.host}:${configHolder.configuration.port}`;
|
76 | }
|
77 |
|
78 |
|
79 | const regRequest = {
|
80 | url: `${hubUri(configHolder.configuration)}/grid/register`,
|
81 | method: 'POST',
|
82 | data: configHolder,
|
83 | };
|
84 |
|
85 | if (configHolder.configuration.register !== true) {
|
86 | logger.debug(`No registration sent (${configHolder.configuration.register} = false)`);
|
87 | return;
|
88 | }
|
89 |
|
90 | const registerCycleInterval = configHolder.configuration.registerCycle;
|
91 | if (isNaN(registerCycleInterval) || registerCycleInterval <= 0) {
|
92 | logger.warn(`'registerCycle' is not a valid positive number. ` +
|
93 | `No registration request will be sent to the grid.`);
|
94 | return;
|
95 | }
|
96 |
|
97 | let first = true;
|
98 | logger.debug(`Starting auto register thread for the grid. ` +
|
99 | `Will try to register every ${registerCycleInterval} ms.`);
|
100 | setInterval(async function registerRetry () {
|
101 | if (first) {
|
102 | first = false;
|
103 | await registerToGrid(regRequest, configHolder);
|
104 | } else if (!await isAlreadyRegistered(configHolder)) {
|
105 |
|
106 | await registerToGrid(regRequest, configHolder);
|
107 | }
|
108 | }, registerCycleInterval);
|
109 | }
|
110 |
|
111 | async function isAlreadyRegistered (configHolder) {
|
112 |
|
113 | const id = configHolder.configuration.id;
|
114 | try {
|
115 | const {data, status} = await axios({
|
116 | url: `${hubUri(configHolder.configuration)}/grid/api/proxy?id=${id}`,
|
117 | timeout: 10000,
|
118 | });
|
119 | if (status !== 200) {
|
120 | throw new Error(`Request failed with code ${status}`);
|
121 | }
|
122 | if (!data.success) {
|
123 |
|
124 | logger.debug(`Grid registration error: ${data.msg}`);
|
125 | }
|
126 | return data.success;
|
127 | } catch (err) {
|
128 | logger.debug(`Hub down or not responding: ${err.message}`);
|
129 | }
|
130 | }
|
131 |
|
132 |
|
133 | export default registerNode;
|