Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 42x 5x 5x 5x 5x 25x 25x 25x 25x 25x 5x 19x 19x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 3x | class ConnectorValidator {
constructor(requiredConnectors = []) {
this.requiredConnectors = requiredConnectors.length > 0 ? requiredConnectors : [
'connector-logger',
'connector-storage',
'connector-registry-client',
'connector-mq-client',
'connector-cookbook'
];
}
/**
* Validates connector usage in service
* @param {object} metadata - Service metadata containing connector info
* @returns {Promise<object>} Validation result
*/
async validate(metadata) {
const result = {
valid: true,
errors: [],
warnings: [],
info: {
connectors: {},
missingRequired: [],
additionalConnectors: []
}
};
try {
const connectors = metadata.connectors || {};
// Check for required connectors
for (const connectorName of this.requiredConnectors) {
const hasConnector = connectors[connectorName] !== undefined;
result.info.connectors[connectorName] = hasConnector;
if (!hasConnector) {
result.warnings.push(`Missing required connector: ${connectorName}`);
result.info.missingRequired.push(connectorName);
} else E{
// Validate connector configuration
const connectorConfig = connectors[connectorName];
if (typeof connectorConfig === 'object') {
// Check for version
if (!connectorConfig.version) {
result.warnings.push(`Connector ${connectorName} missing version information`);
} else {
// Validate version format
if (!this.isValidVersion(connectorConfig.version)) {
result.warnings.push(`Connector ${connectorName} has invalid version format: ${connectorConfig.version}`);
}
}
// Check if enabled
if (connectorConfig.enabled === false) {
result.warnings.push(`Connector ${connectorName} is disabled`);
}
// Check for configuration
if (!connectorConfig.config && connectorConfig.enabled !== false) {
result.info.connectors[connectorName] = {
present: true,
configured: false
};
} else {
result.info.connectors[connectorName] = {
present: true,
configured: true,
version: connectorConfig.version
};
}
}
}
}
// Check for additional connectors (not in required list)
Object.keys(connectors).forEach(connectorName => {
Eif (!this.requiredConnectors.includes(connectorName)) {
result.info.additionalConnectors.push(connectorName);
}
});
// Special checks for specific connectors
this.validateSpecialConnectors(connectors, result);
// Check health endpoint
Eif (!metadata.health && !metadata.healthEndpoint) {
result.warnings.push('Service should define a health check endpoint');
}
// Check for workflow support
Eif (!connectors['connector-cookbook']?.enabled) {
result.warnings.push('Service should support workflow processing via connector-cookbook');
}
// Check for logging
Eif (!connectors['connector-logger']) {
result.errors.push('connector-logger is critical for service observability');
}
// Determine overall validity
Eif (result.info.missingRequired.length > 0) {
result.valid = false;
}
Eif (result.errors.length > 0) {
result.valid = false;
}
} catch (error) {
result.valid = false;
result.errors.push(`Connector validation error: ${error.message}`);
}
return result;
}
/**
* Validate special connector requirements
* @param {object} connectors - Connectors configuration
* @param {object} result - Validation result object to update
*/
validateSpecialConnectors(connectors, result) {
// MQ Client specific checks
Iif (connectors['connector-mq-client']) {
const mqConfig = connectors['connector-mq-client'];
if (mqConfig.config) {
if (!mqConfig.config.url && !mqConfig.config.host) {
result.warnings.push('connector-mq-client should have URL or host configured');
}
}
}
// Storage connector checks
Iif (connectors['connector-storage']) {
const storageConfig = connectors['connector-storage'];
if (storageConfig.config) {
if (!storageConfig.config.bucket && !storageConfig.config.defaultBucket) {
result.warnings.push('connector-storage should have bucket configured');
}
}
}
// Registry client checks
Iif (connectors['connector-registry-client']) {
const registryConfig = connectors['connector-registry-client'];
if (registryConfig.config) {
if (!registryConfig.config.serviceName) {
result.errors.push('connector-registry-client must have serviceName configured');
}
}
}
// Logger checks
Iif (connectors['connector-logger']) {
const loggerConfig = connectors['connector-logger'];
if (loggerConfig.config) {
if (!loggerConfig.config.level) {
result.warnings.push('connector-logger should have log level configured');
}
}
}
}
/**
* Check if version string is valid semver
* @param {string} version - Version string to validate
* @returns {boolean} Validation result
*/
isValidVersion(version) {
// Simple semver check
const semverRegex = /^\d+\.\d+\.\d+(-[\w\.]+)?(\+[\w\.]+)?$/;
return semverRegex.test(version);
}
/**
* Generate connector report
* @param {object} metadata - Service metadata
* @returns {object} Connector report
*/
generateReport(metadata) {
const connectors = metadata.connectors || {};
const report = {
summary: {
total: Object.keys(connectors).length,
required: this.requiredConnectors.length,
missing: 0,
disabled: 0
},
details: []
};
// Check each required connector
this.requiredConnectors.forEach(name => {
const connector = connectors[name];
const detail = {
name,
required: true,
present: !!connector,
enabled: connector ? connector.enabled !== false : false,
version: connector?.version || null,
configured: connector?.config ? true : false
};
if (!detail.present) {
report.summary.missing++;
}
if (detail.present && !detail.enabled) {
report.summary.disabled++;
}
report.details.push(detail);
});
// Add additional connectors
Object.keys(connectors).forEach(name => {
if (!this.requiredConnectors.includes(name)) {
const connector = connectors[name];
report.details.push({
name,
required: false,
present: true,
enabled: connector.enabled !== false,
version: connector.version || null,
configured: connector.config ? true : false
});
}
});
return report;
}
}
module.exports = ConnectorValidator; |