Implement Server CRUD with bool type fix and auto-increment IDs
CRITICAL FIX: Changed boolean fields from int32 to bool type - Enabled, DeactivateEcho, DeactivateLiveCheck now use proper bool type (type code 1) - Previous int32 implementation (type code 4) caused servers to be written but not recognized by GeViSet - Fixed field order to match working reference implementation Server CRUD Implementation: - Create, Read, Update, Delete operations via gRPC and REST API - Auto-increment server ID logic to prevent conflicts - Proper field ordering: Alias, DeactivateEcho, DeactivateLiveCheck, Enabled, Host, Password, User Files Added/Modified: - src/sdk-bridge/GeViScopeBridge/Services/ConfigurationServiceImplementation.cs (bool type fix, CRUD methods) - src/sdk-bridge/Protos/configuration.proto (protocol definitions) - src/api/routers/configuration.py (REST endpoints) - src/api/protos/ (generated protobuf files) - SERVER_CRUD_IMPLEMENTATION.md (comprehensive documentation) Verified: - Servers persist correctly in GeViSoft configuration - Servers visible in GeViSet with correct boolean values - Action mappings CRUD functional - All test scripts working (server_manager.py, cleanup_to_base.py, add_claude_test_data.py) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
298
src/sdk-bridge/Protos/configuration.proto
Normal file
298
src/sdk-bridge/Protos/configuration.proto
Normal file
@@ -0,0 +1,298 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package configuration;
|
||||
|
||||
option csharp_namespace = "GeViScopeBridge.Protos";
|
||||
|
||||
service ConfigurationService {
|
||||
// Read and parse complete configuration from GeViServer
|
||||
rpc ReadConfiguration(ReadConfigurationRequest) returns (ConfigurationResponse);
|
||||
|
||||
// Export configuration as JSON string
|
||||
rpc ExportConfigurationJson(ExportJsonRequest) returns (JsonExportResponse);
|
||||
|
||||
// Modify configuration values and write back to server
|
||||
rpc ModifyConfiguration(ModifyConfigurationRequest) returns (ModifyConfigurationResponse);
|
||||
|
||||
// Import complete configuration from JSON and write to GeViServer
|
||||
rpc ImportConfiguration(ImportConfigurationRequest) returns (ImportConfigurationResponse);
|
||||
|
||||
// SELECTIVE/TARGETED READ METHODS (Fast, lightweight)
|
||||
|
||||
// Read ONLY action mappings (Rules markers) - optimized for speed
|
||||
rpc ReadActionMappings(ReadActionMappingsRequest) returns (ActionMappingsResponse);
|
||||
|
||||
// Read specific markers by name - extensible for future config types
|
||||
rpc ReadSpecificMarkers(ReadSpecificMarkersRequest) returns (SelectiveConfigResponse);
|
||||
|
||||
// ACTION MAPPING WRITE METHODS
|
||||
|
||||
// Create a new action mapping
|
||||
rpc CreateActionMapping(CreateActionMappingRequest) returns (ActionMappingOperationResponse);
|
||||
|
||||
// Update an existing action mapping by ID
|
||||
rpc UpdateActionMapping(UpdateActionMappingRequest) returns (ActionMappingOperationResponse);
|
||||
|
||||
// Delete an action mapping by ID
|
||||
rpc DeleteActionMapping(DeleteActionMappingRequest) returns (ActionMappingOperationResponse);
|
||||
|
||||
// SERVER CONFIGURATION WRITE METHODS (G-CORE SERVERS)
|
||||
|
||||
// Create a new G-core server
|
||||
rpc CreateServer(CreateServerRequest) returns (ServerOperationResponse);
|
||||
|
||||
// Update an existing G-core server
|
||||
rpc UpdateServer(UpdateServerRequest) returns (ServerOperationResponse);
|
||||
|
||||
// Delete a G-core server
|
||||
rpc DeleteServer(DeleteServerRequest) returns (ServerOperationResponse);
|
||||
|
||||
// TREE FORMAT (RECOMMENDED)
|
||||
|
||||
// Read configuration as hierarchical folder tree - much more readable than flat format
|
||||
rpc ReadConfigurationTree(ReadConfigurationTreeRequest) returns (ConfigurationTreeResponse);
|
||||
|
||||
// REGISTRY EXPLORATION METHODS
|
||||
|
||||
// List top-level registry nodes
|
||||
rpc ListRegistryNodes(ListRegistryNodesRequest) returns (RegistryNodesResponse);
|
||||
|
||||
// Get details about a specific registry node
|
||||
rpc GetRegistryNodeDetails(GetRegistryNodeDetailsRequest) returns (RegistryNodeDetailsResponse);
|
||||
|
||||
// Search for action mapping paths in registry
|
||||
rpc SearchActionMappingPaths(SearchActionMappingPathsRequest) returns (ActionMappingPathsResponse);
|
||||
}
|
||||
|
||||
message ReadConfigurationRequest {
|
||||
// Empty - uses connection from setup client
|
||||
}
|
||||
|
||||
message ConfigurationStatistics {
|
||||
int32 total_nodes = 1;
|
||||
int32 boolean_count = 2;
|
||||
int32 integer_count = 3;
|
||||
int32 string_count = 4;
|
||||
int32 property_count = 5;
|
||||
int32 marker_count = 6;
|
||||
int32 rules_section_count = 7;
|
||||
}
|
||||
|
||||
message ConfigNode {
|
||||
int32 start_offset = 1;
|
||||
int32 end_offset = 2;
|
||||
string node_type = 3; // "boolean", "integer", "string", "property", "marker"
|
||||
string name = 4;
|
||||
string value = 5; // Serialized as string
|
||||
string value_type = 6;
|
||||
}
|
||||
|
||||
message ConfigurationResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
int32 file_size = 3;
|
||||
string header = 4;
|
||||
repeated ConfigNode nodes = 5;
|
||||
ConfigurationStatistics statistics = 6;
|
||||
}
|
||||
|
||||
message ExportJsonRequest {
|
||||
// Empty - exports current configuration
|
||||
}
|
||||
|
||||
message JsonExportResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
string json_data = 3;
|
||||
int32 json_size = 4;
|
||||
}
|
||||
|
||||
message NodeModification {
|
||||
int32 start_offset = 1;
|
||||
string node_type = 2; // "boolean", "integer", "string"
|
||||
string new_value = 3; // Serialized as string
|
||||
}
|
||||
|
||||
message ModifyConfigurationRequest {
|
||||
repeated NodeModification modifications = 1;
|
||||
}
|
||||
|
||||
message ModifyConfigurationResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
int32 modifications_applied = 3;
|
||||
}
|
||||
|
||||
message ImportConfigurationRequest {
|
||||
string json_data = 1; // Complete configuration as JSON string
|
||||
}
|
||||
|
||||
message ImportConfigurationResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
int32 bytes_written = 3;
|
||||
int32 nodes_imported = 4;
|
||||
}
|
||||
|
||||
// ========== SELECTIVE READ MESSAGES ==========
|
||||
|
||||
message ReadActionMappingsRequest {
|
||||
// Empty - reads action mappings from current configuration
|
||||
}
|
||||
|
||||
message ActionParameter {
|
||||
string name = 1; // Parameter name (e.g., "VideoInput", "G-core alias")
|
||||
string value = 2; // Parameter value (e.g., "101027", "gscope-cdu-3")
|
||||
}
|
||||
|
||||
message ActionDefinition {
|
||||
string action = 1; // Action name (e.g., "CrossSwitch C_101027 -> M")
|
||||
repeated ActionParameter parameters = 2; // Named parameters
|
||||
}
|
||||
|
||||
message ConfigActionMapping {
|
||||
string name = 1; // Mapping name (e.g., "CrossSwitch C_101027 -> M")
|
||||
repeated ActionDefinition input_actions = 2; // Trigger/condition actions
|
||||
repeated ActionDefinition output_actions = 3; // Response actions
|
||||
int32 start_offset = 4;
|
||||
int32 end_offset = 5;
|
||||
|
||||
// Deprecated - kept for backward compatibility
|
||||
repeated string actions = 6; // List of action strings (old format)
|
||||
}
|
||||
|
||||
message ActionMappingsResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
repeated ConfigActionMapping mappings = 3;
|
||||
int32 total_count = 4;
|
||||
}
|
||||
|
||||
message ReadSpecificMarkersRequest {
|
||||
repeated string marker_names = 1; // Names of markers to extract (e.g., "Rules", "Camera")
|
||||
}
|
||||
|
||||
message SelectiveConfigResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
int32 file_size = 3;
|
||||
repeated string requested_markers = 4;
|
||||
repeated ConfigNode extracted_nodes = 5;
|
||||
int32 markers_found = 6;
|
||||
}
|
||||
|
||||
// ========== ACTION MAPPING WRITE MESSAGES ==========
|
||||
|
||||
message ActionMappingInput {
|
||||
string name = 1; // Mapping caption (required for GeViSet display)
|
||||
repeated ActionDefinition input_actions = 2; // Trigger actions
|
||||
repeated ActionDefinition output_actions = 3; // Response actions (required)
|
||||
int32 video_input = 4; // Video input ID (optional, but recommended for GeViSet display)
|
||||
}
|
||||
|
||||
message CreateActionMappingRequest {
|
||||
ActionMappingInput mapping = 1;
|
||||
}
|
||||
|
||||
message UpdateActionMappingRequest {
|
||||
int32 mapping_id = 1; // 1-based ID of mapping to update
|
||||
ActionMappingInput mapping = 2; // New data (fields can be partial)
|
||||
}
|
||||
|
||||
message DeleteActionMappingRequest {
|
||||
int32 mapping_id = 1; // 1-based ID of mapping to delete
|
||||
}
|
||||
|
||||
message ActionMappingOperationResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
ConfigActionMapping mapping = 3; // Created/updated mapping (null for delete)
|
||||
string message = 4; // Success/info message
|
||||
}
|
||||
|
||||
// REGISTRY EXPLORATION MESSAGES
|
||||
|
||||
message ListRegistryNodesRequest {
|
||||
// Empty - lists top-level nodes
|
||||
}
|
||||
|
||||
message RegistryNodesResponse {
|
||||
bool success = 1;
|
||||
repeated string node_paths = 2;
|
||||
string error_message = 3;
|
||||
}
|
||||
|
||||
message GetRegistryNodeDetailsRequest {
|
||||
string node_path = 1;
|
||||
}
|
||||
|
||||
message RegistryNodeDetailsResponse {
|
||||
bool success = 1;
|
||||
string details = 2;
|
||||
string error_message = 3;
|
||||
}
|
||||
|
||||
message SearchActionMappingPathsRequest {
|
||||
// Empty - searches for action mapping related nodes
|
||||
}
|
||||
|
||||
message ActionMappingPathsResponse {
|
||||
bool success = 1;
|
||||
repeated string paths = 2;
|
||||
string error_message = 3;
|
||||
}
|
||||
|
||||
// ========== SERVER CRUD MESSAGES ==========
|
||||
|
||||
message ServerData {
|
||||
string id = 1; // Server ID (folder name in GeViGCoreServer)
|
||||
string alias = 2; // Alias (display name)
|
||||
string host = 3; // Host/IP address
|
||||
string user = 4; // Username
|
||||
string password = 5; // Password
|
||||
bool enabled = 6; // Enabled flag
|
||||
bool deactivate_echo = 7; // DeactivateEcho flag
|
||||
bool deactivate_live_check = 8; // DeactivateLiveCheck flag
|
||||
}
|
||||
|
||||
message CreateServerRequest {
|
||||
ServerData server = 1;
|
||||
}
|
||||
|
||||
message UpdateServerRequest {
|
||||
string server_id = 1; // ID of server to update
|
||||
ServerData server = 2; // New server data (fields can be partial)
|
||||
}
|
||||
|
||||
message DeleteServerRequest {
|
||||
string server_id = 1; // ID of server to delete
|
||||
}
|
||||
|
||||
message ServerOperationResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
ServerData server = 3; // Created/updated server (null for delete)
|
||||
string message = 4; // Success/info message
|
||||
int32 bytes_written = 5; // Size of configuration written
|
||||
}
|
||||
|
||||
// ========== TREE FORMAT MESSAGES ==========
|
||||
|
||||
message ReadConfigurationTreeRequest {
|
||||
// Empty - reads entire configuration as tree
|
||||
}
|
||||
|
||||
message TreeNode {
|
||||
string type = 1; // "folder", "bool", "byte", "int16", "int32", "int64", "string"
|
||||
string name = 2; // Node name
|
||||
int64 int_value = 3; // For integer/bool types
|
||||
string string_value = 4; // For string types
|
||||
repeated TreeNode children = 5; // For folders (hierarchical structure)
|
||||
}
|
||||
|
||||
message ConfigurationTreeResponse {
|
||||
bool success = 1;
|
||||
string error_message = 2;
|
||||
TreeNode root = 3; // Root folder node containing entire configuration tree
|
||||
int32 total_nodes = 4; // Total node count (all levels)
|
||||
}
|
||||
Reference in New Issue
Block a user