Implement LockState & UnlockState provider methods (#37711)

This commit is contained in:
Radek Simko 2025-10-03 10:02:02 +01:00 committed by GitHub
parent ea20db63fb
commit 922fdb2382
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 1158 additions and 428 deletions

View file

@ -395,6 +395,11 @@ service Provider {
// WriteStateBytes streams byte chunks of a given state file into a state store
rpc WriteStateBytes(stream WriteStateBytes.RequestChunk) returns (WriteStateBytes.Response);
// LockState locks a given state (i.e. CE workspace)
rpc LockState(LockState.Request) returns (LockState.Response);
// UnlockState unlocks a given state (i.e. CE workspace)
rpc UnlockState(UnlockState.Request) returns (UnlockState.Response);
// GetStates returns a list of all states (i.e. CE workspaces) managed by a given state store
rpc GetStates(GetStates.Request) returns (GetStates.Response);
// DeleteState instructs a given state store to delete a specific state (i.e. a CE workspace)
@ -968,6 +973,30 @@ message StateRange {
int64 end = 2;
}
message LockState {
message Request {
string type_name = 1;
string state_id = 2;
// operation represents an ongoing operation due to which lock is held (e.g. refresh, plan, apply)
string operation = 3;
}
message Response {
string lock_id = 1;
repeated Diagnostic diagnostics = 2;
}
}
message UnlockState {
message Request {
string type_name = 1;
string state_id = 2;
string lock_id = 3;
}
message Response {
repeated Diagnostic diagnostics = 1;
}
}
message GetStates {
message Request {
string type_name = 1;

View file

@ -307,6 +307,18 @@ func (p *Provider) WriteStateBytes(req providers.WriteStateBytesRequest) provide
return resp
}
func (p *Provider) LockState(req providers.LockStateRequest) providers.LockStateResponse {
var resp providers.LockStateResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported state store type %q", req.TypeName))
return resp
}
func (p *Provider) UnlockState(req providers.UnlockStateRequest) providers.UnlockStateResponse {
var resp providers.UnlockStateResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported state store type %q", req.TypeName))
return resp
}
func (p *Provider) GetStates(req providers.GetStatesRequest) providers.GetStatesResponse {
var resp providers.GetStatesResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported state store type %q", req.TypeName))

View file

@ -915,6 +915,14 @@ func (p *provider6) WriteStateBytes(srv tfplugin6.Provider_WriteStateBytesServer
panic("not implemented")
}
func (p *provider6) LockState(ctx context.Context, req *tfplugin6.LockState_Request) (*tfplugin6.LockState_Response, error) {
panic("not implemented")
}
func (p *provider6) UnlockState(ctx context.Context, req *tfplugin6.UnlockState_Request) (*tfplugin6.UnlockState_Response, error) {
panic("not implemented")
}
func (p *provider6) GetStates(ctx context.Context, req *tfplugin6.GetStates_Request) (*tfplugin6.GetStates_Response, error) {
panic("not implemented")
}

View file

@ -1452,6 +1452,14 @@ func (p *GRPCProvider) WriteStateBytes(r providers.WriteStateBytesRequest) provi
panic("not implemented")
}
func (p *GRPCProvider) LockState(r providers.LockStateRequest) providers.LockStateResponse {
panic("not implemented")
}
func (p *GRPCProvider) UnlockState(r providers.UnlockStateRequest) providers.UnlockStateResponse {
panic("not implemented")
}
func (p *GRPCProvider) GetStates(r providers.GetStatesRequest) providers.GetStatesResponse {
panic("not implemented")
}

View file

@ -1738,6 +1738,67 @@ func (p *GRPCProvider) WriteStateBytes(r providers.WriteStateBytesRequest) (resp
return resp
}
func (p *GRPCProvider) LockState(r providers.LockStateRequest) (resp providers.LockStateResponse) {
logger.Trace("GRPCProvider.v6: LockState")
schema := p.GetProviderSchema()
if schema.Diagnostics.HasErrors() {
resp.Diagnostics = schema.Diagnostics
return resp
}
_, ok := schema.StateStores[r.TypeName]
if !ok {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unknown state store type %q", r.TypeName))
return resp
}
protoReq := &proto6.LockState_Request{
TypeName: r.TypeName,
StateId: r.StateId,
Operation: r.Operation,
}
protoResp, err := p.client.LockState(p.ctx, protoReq)
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
return resp
}
resp.LockId = protoResp.LockId
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
return resp
}
func (p *GRPCProvider) UnlockState(r providers.UnlockStateRequest) (resp providers.UnlockStateResponse) {
logger.Trace("GRPCProvider.v6: UnlockState")
schema := p.GetProviderSchema()
if schema.Diagnostics.HasErrors() {
resp.Diagnostics = schema.Diagnostics
return resp
}
_, ok := schema.StateStores[r.TypeName]
if !ok {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unknown state store type %q", r.TypeName))
return resp
}
protoReq := &proto6.UnlockState_Request{
TypeName: r.TypeName,
StateId: r.StateId,
LockId: r.LockId,
}
protoResp, err := p.client.UnlockState(p.ctx, protoReq)
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
return resp
}
resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))
return resp
}
func (p *GRPCProvider) SetStateStoreChunkSize(typeName string, size int) {
p.mu.Lock()
defer p.mu.Unlock()

View file

@ -343,6 +343,26 @@ func (mr *MockProviderClientMockRecorder) ListResource(ctx, in any, opts ...any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResource", reflect.TypeOf((*MockProviderClient)(nil).ListResource), varargs...)
}
// LockState mocks base method.
func (m *MockProviderClient) LockState(ctx context.Context, in *tfplugin6.LockState_Request, opts ...grpc.CallOption) (*tfplugin6.LockState_Response, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "LockState", varargs...)
ret0, _ := ret[0].(*tfplugin6.LockState_Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// LockState indicates an expected call of LockState.
func (mr *MockProviderClientMockRecorder) LockState(ctx, in any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockState", reflect.TypeOf((*MockProviderClient)(nil).LockState), varargs...)
}
// MoveResourceState mocks base method.
func (m *MockProviderClient) MoveResourceState(ctx context.Context, in *tfplugin6.MoveResourceState_Request, opts ...grpc.CallOption) (*tfplugin6.MoveResourceState_Response, error) {
m.ctrl.T.Helper()
@ -523,6 +543,26 @@ func (mr *MockProviderClientMockRecorder) StopProvider(ctx, in any, opts ...any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopProvider", reflect.TypeOf((*MockProviderClient)(nil).StopProvider), varargs...)
}
// UnlockState mocks base method.
func (m *MockProviderClient) UnlockState(ctx context.Context, in *tfplugin6.UnlockState_Request, opts ...grpc.CallOption) (*tfplugin6.UnlockState_Response, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UnlockState", varargs...)
ret0, _ := ret[0].(*tfplugin6.UnlockState_Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UnlockState indicates an expected call of UnlockState.
func (mr *MockProviderClientMockRecorder) UnlockState(ctx, in any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnlockState", reflect.TypeOf((*MockProviderClient)(nil).UnlockState), varargs...)
}
// UpgradeResourceIdentity mocks base method.
func (m *MockProviderClient) UpgradeResourceIdentity(ctx context.Context, in *tfplugin6.UpgradeResourceIdentity_Request, opts ...grpc.CallOption) (*tfplugin6.UpgradeResourceIdentity_Response, error) {
m.ctrl.T.Helper()

View file

@ -325,6 +325,14 @@ func (s simple) WriteStateBytes(req providers.WriteStateBytesRequest) providers.
panic("not implemented")
}
func (s simple) LockState(req providers.LockStateRequest) providers.LockStateResponse {
panic("not implemented")
}
func (s simple) UnlockState(req providers.UnlockStateRequest) providers.UnlockStateResponse {
panic("not implemented")
}
func (s simple) GetStates(req providers.GetStatesRequest) providers.GetStatesResponse {
panic("not implemented")
}

View file

@ -285,6 +285,14 @@ func (s simple) WriteStateBytes(req providers.WriteStateBytesRequest) providers.
panic("not implemented")
}
func (s simple) LockState(req providers.LockStateRequest) providers.LockStateResponse {
panic("not implemented")
}
func (s simple) UnlockState(req providers.UnlockStateRequest) providers.UnlockStateResponse {
panic("not implemented")
}
func (s simple) GetStates(req providers.GetStatesRequest) providers.GetStatesResponse {
// provider-simple uses protocol version 5, which does not include the RPC that maps to this method
panic("not implemented")

View file

@ -444,6 +444,14 @@ func (m *Mock) WriteStateBytes(req WriteStateBytesRequest) WriteStateBytesRespon
return m.Provider.WriteStateBytes(req)
}
func (m *Mock) LockState(req LockStateRequest) LockStateResponse {
return m.Provider.LockState(req)
}
func (m *Mock) UnlockState(req UnlockStateRequest) UnlockStateResponse {
return m.Provider.UnlockState(req)
}
func (m *Mock) GetStates(req GetStatesRequest) GetStatesResponse {
return m.Provider.GetStates(req)
}

View file

@ -128,6 +128,11 @@ type Interface interface {
// WriteStateBytes streams byte chunks of a given state file into a state store
WriteStateBytes(WriteStateBytesRequest) WriteStateBytesResponse
// LockState locks a given state (i.e. CE workspace)
LockState(LockStateRequest) LockStateResponse
// UnlockState unlocks a given state (i.e. CE workspace)
UnlockState(UnlockStateRequest) UnlockStateResponse
// GetStates returns a list of all states (i.e. CE workspaces) managed by a given state store
GetStates(GetStatesRequest) GetStatesResponse
// DeleteState instructs a given state store to delete a specific state (i.e. a CE workspace)
@ -903,6 +908,29 @@ type WriteStateBytesResponse struct {
Diagnostics tfdiags.Diagnostics
}
type LockStateRequest struct {
TypeName string
StateId string
Operation string
}
type LockStateResponse struct {
LockId string
// Diagnostics contains any warnings or errors from the method call.
Diagnostics tfdiags.Diagnostics
}
type UnlockStateRequest struct {
TypeName string
StateId string
LockId string
}
type UnlockStateResponse struct {
// Diagnostics contains any warnings or errors from the method call.
Diagnostics tfdiags.Diagnostics
}
type GetStatesRequest struct {
// TypeName is the name of the state store to request the list of states from
TypeName string

View file

@ -156,6 +156,16 @@ type MockProvider struct {
WriteStateBytesFn func(providers.WriteStateBytesRequest) providers.WriteStateBytesResponse
WriteStateBytesResponse providers.WriteStateBytesResponse
LockStateCalled bool
LockStateResponse providers.LockStateResponse
LockStateRequest providers.LockStateRequest
LockStateFn func(providers.LockStateRequest) providers.LockStateResponse
UnlockStateCalled bool
UnlockStateResponse providers.UnlockStateResponse
UnlockStateRequest providers.UnlockStateRequest
UnlockStateFn func(providers.UnlockStateRequest) providers.UnlockStateResponse
GetStatesCalled bool
GetStatesResponse *providers.GetStatesResponse
GetStatesRequest providers.GetStatesRequest
@ -340,6 +350,32 @@ func (p *MockProvider) WriteStateBytes(r providers.WriteStateBytesRequest) (resp
return p.WriteStateBytesResponse
}
func (p *MockProvider) LockState(r providers.LockStateRequest) (resp providers.LockStateResponse) {
p.Lock()
defer p.Unlock()
p.LockStateCalled = true
p.LockStateRequest = r
if p.LockStateFn != nil {
return p.LockStateFn(r)
}
return p.LockStateResponse
}
func (p *MockProvider) UnlockState(r providers.UnlockStateRequest) (resp providers.UnlockStateResponse) {
p.Lock()
defer p.Unlock()
p.UnlockStateCalled = true
p.UnlockStateRequest = r
if p.UnlockStateFn != nil {
return p.UnlockStateFn(r)
}
return p.UnlockStateResponse
}
func (p *MockProvider) ValidateEphemeralResourceConfig(r providers.ValidateEphemeralResourceConfigRequest) (resp providers.ValidateEphemeralResourceConfigResponse) {
defer p.beginWrite()()

View file

@ -150,6 +150,14 @@ func (provider *mockProvider) DeleteState(req providers.DeleteStateRequest) prov
panic("not implemented in mock")
}
func (provider *mockProvider) LockState(req providers.LockStateRequest) providers.LockStateResponse {
panic("not implemented in mock")
}
func (provider *mockProvider) UnlockState(req providers.UnlockStateRequest) providers.UnlockStateResponse {
panic("not implemented in mock")
}
func (provider *mockProvider) PlanAction(providers.PlanActionRequest) providers.PlanActionResponse {
panic("not implemented in mock")
}

View file

@ -304,6 +304,34 @@ func (p *erroredProvider) WriteStateBytes(providers.WriteStateBytesRequest) prov
}
}
// LockState implements providers.Interface.
func (p *erroredProvider) LockState(providers.LockStateRequest) providers.LockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Provider configuration is invalid",
"Cannot lock state managed by this state store because its associated provider configuration is invalid.",
nil, // nil attribute path means the overall configuration block
))
return providers.LockStateResponse{
Diagnostics: diags,
}
}
// UnlockState implements providers.Interface.
func (p *erroredProvider) UnlockState(providers.UnlockStateRequest) providers.UnlockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Provider configuration is invalid",
"Cannot unlock state managed by this state store because its associated provider configuration is invalid.",
nil, // nil attribute path means the overall configuration block
))
return providers.UnlockStateResponse{
Diagnostics: diags,
}
}
// GetStates implements providers.Interface.
func (p *erroredProvider) GetStates(providers.GetStatesRequest) providers.GetStatesResponse {
var diags tfdiags.Diagnostics

View file

@ -349,6 +349,32 @@ func (o *offlineProvider) DeleteState(providers.DeleteStateRequest) providers.De
}
}
func (o *offlineProvider) LockState(providers.LockStateRequest) providers.LockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Called LockState on an unconfigured provider",
"Cannot use this state store to lock a state because this provider is not configured. This is a bug in Terraform - please report it.",
nil, // nil attribute path means the overall configuration block
))
return providers.LockStateResponse{
Diagnostics: diags,
}
}
func (o *offlineProvider) UnlockState(providers.UnlockStateRequest) providers.UnlockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Called UnlockState on an unconfigured provider",
"Cannot use this state store to unlock a state because this provider is not configured. This is a bug in Terraform - please report it.",
nil, // nil attribute path means the overall configuration block
))
return providers.UnlockStateResponse{
Diagnostics: diags,
}
}
// PlanAction implements providers.Interface.
func (o *offlineProvider) PlanAction(request providers.PlanActionRequest) providers.PlanActionResponse {
var diags tfdiags.Diagnostics

View file

@ -369,6 +369,32 @@ func (u *unknownProvider) WriteStateBytes(providers.WriteStateBytesRequest) prov
}
}
func (u *unknownProvider) LockState(req providers.LockStateRequest) providers.LockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Provider configuration is unknown",
"Cannot lock to this state store because its associated provider configuration is unknown.",
nil, // nil attribute path means the overall configuration block
))
return providers.LockStateResponse{
Diagnostics: diags,
}
}
func (u *unknownProvider) UnlockState(req providers.UnlockStateRequest) providers.UnlockStateResponse {
var diags tfdiags.Diagnostics
diags = diags.Append(tfdiags.AttributeValue(
tfdiags.Error,
"Provider configuration is unknown",
"Cannot unlock to this state store because its associated provider configuration is unknown.",
nil, // nil attribute path means the overall configuration block
))
return providers.UnlockStateResponse{
Diagnostics: diags,
}
}
// GetStates implements providers.Interface.
func (u *unknownProvider) GetStates(providers.GetStatesRequest) providers.GetStatesResponse {
var diags tfdiags.Diagnostics

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,8 @@ const (
Provider_ConfigureStateStore_FullMethodName = "/tfplugin6.Provider/ConfigureStateStore"
Provider_ReadStateBytes_FullMethodName = "/tfplugin6.Provider/ReadStateBytes"
Provider_WriteStateBytes_FullMethodName = "/tfplugin6.Provider/WriteStateBytes"
Provider_LockState_FullMethodName = "/tfplugin6.Provider/LockState"
Provider_UnlockState_FullMethodName = "/tfplugin6.Provider/UnlockState"
Provider_GetStates_FullMethodName = "/tfplugin6.Provider/GetStates"
Provider_DeleteState_FullMethodName = "/tfplugin6.Provider/DeleteState"
Provider_PlanAction_FullMethodName = "/tfplugin6.Provider/PlanAction"
@ -129,6 +131,10 @@ type ProviderClient interface {
ReadStateBytes(ctx context.Context, in *ReadStateBytes_Request, opts ...grpc.CallOption) (Provider_ReadStateBytesClient, error)
// WriteStateBytes streams byte chunks of a given state file into a state store
WriteStateBytes(ctx context.Context, opts ...grpc.CallOption) (Provider_WriteStateBytesClient, error)
// LockState locks a given state (i.e. CE workspace)
LockState(ctx context.Context, in *LockState_Request, opts ...grpc.CallOption) (*LockState_Response, error)
// UnlockState unlocks a given state (i.e. CE workspace)
UnlockState(ctx context.Context, in *UnlockState_Request, opts ...grpc.CallOption) (*UnlockState_Response, error)
// GetStates returns a list of all states (i.e. CE workspaces) managed by a given state store
GetStates(ctx context.Context, in *GetStates_Request, opts ...grpc.CallOption) (*GetStates_Response, error)
// DeleteState instructs a given state store to delete a specific state (i.e. a CE workspace)
@ -472,6 +478,24 @@ func (x *providerWriteStateBytesClient) CloseAndRecv() (*WriteStateBytes_Respons
return m, nil
}
func (c *providerClient) LockState(ctx context.Context, in *LockState_Request, opts ...grpc.CallOption) (*LockState_Response, error) {
out := new(LockState_Response)
err := c.cc.Invoke(ctx, Provider_LockState_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *providerClient) UnlockState(ctx context.Context, in *UnlockState_Request, opts ...grpc.CallOption) (*UnlockState_Response, error) {
out := new(UnlockState_Response)
err := c.cc.Invoke(ctx, Provider_UnlockState_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *providerClient) GetStates(ctx context.Context, in *GetStates_Request, opts ...grpc.CallOption) (*GetStates_Response, error) {
out := new(GetStates_Response)
err := c.cc.Invoke(ctx, Provider_GetStates_FullMethodName, in, out, opts...)
@ -602,6 +626,10 @@ type ProviderServer interface {
ReadStateBytes(*ReadStateBytes_Request, Provider_ReadStateBytesServer) error
// WriteStateBytes streams byte chunks of a given state file into a state store
WriteStateBytes(Provider_WriteStateBytesServer) error
// LockState locks a given state (i.e. CE workspace)
LockState(context.Context, *LockState_Request) (*LockState_Response, error)
// UnlockState unlocks a given state (i.e. CE workspace)
UnlockState(context.Context, *UnlockState_Request) (*UnlockState_Response, error)
// GetStates returns a list of all states (i.e. CE workspaces) managed by a given state store
GetStates(context.Context, *GetStates_Request) (*GetStates_Response, error)
// DeleteState instructs a given state store to delete a specific state (i.e. a CE workspace)
@ -702,6 +730,12 @@ func (UnimplementedProviderServer) ReadStateBytes(*ReadStateBytes_Request, Provi
func (UnimplementedProviderServer) WriteStateBytes(Provider_WriteStateBytesServer) error {
return status.Errorf(codes.Unimplemented, "method WriteStateBytes not implemented")
}
func (UnimplementedProviderServer) LockState(context.Context, *LockState_Request) (*LockState_Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method LockState not implemented")
}
func (UnimplementedProviderServer) UnlockState(context.Context, *UnlockState_Request) (*UnlockState_Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnlockState not implemented")
}
func (UnimplementedProviderServer) GetStates(context.Context, *GetStates_Request) (*GetStates_Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetStates not implemented")
}
@ -1250,6 +1284,42 @@ func (x *providerWriteStateBytesServer) Recv() (*WriteStateBytes_RequestChunk, e
return m, nil
}
func _Provider_LockState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LockState_Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ProviderServer).LockState(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Provider_LockState_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ProviderServer).LockState(ctx, req.(*LockState_Request))
}
return interceptor(ctx, in, info, handler)
}
func _Provider_UnlockState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UnlockState_Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ProviderServer).UnlockState(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Provider_UnlockState_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ProviderServer).UnlockState(ctx, req.(*UnlockState_Request))
}
return interceptor(ctx, in, info, handler)
}
func _Provider_GetStates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetStates_Request)
if err := dec(in); err != nil {
@ -1468,6 +1538,14 @@ var Provider_ServiceDesc = grpc.ServiceDesc{
MethodName: "ConfigureStateStore",
Handler: _Provider_ConfigureStateStore_Handler,
},
{
MethodName: "LockState",
Handler: _Provider_LockState_Handler,
},
{
MethodName: "UnlockState",
Handler: _Provider_UnlockState_Handler,
},
{
MethodName: "GetStates",
Handler: _Provider_GetStates_Handler,