Skip to content

Commit

Permalink
fix: update get-host-by-id to properly update host object "status" (i…
Browse files Browse the repository at this point in the history
…n manager and datastore)
  • Loading branch information
scott-howe-1 committed Sep 19, 2024
1 parent 82963c8 commit 6e01adb
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 92 deletions.
137 changes: 64 additions & 73 deletions pkg/api/api_default_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,13 @@ func (cfm *CfmApiService) BladesPost(ctx context.Context, applianceId string, cr
if len(appliance.Blades) == MAX_COUNT_BLADES {
if datastore.DStore().GetDataStore().ContainsBlade(credentials.CustomId, appliance.Id) {

// If blade limit exceeded AND blade in datastore, set it inactive
// If blade limit exceeded AND blade in datastore, set it offline
req := datastore.BladeUpdateRequest{
ApplianceId: appliance.Id,
BladeId: credentials.CustomId,
Status: datastore.Inactive,
Status: common.OFFLINE,
}
datastore.DStore().GetDataStore().UpdateBlade(&req)
datastore.DStore().GetDataStore().UpdateBlade(ctx, &req)
datastore.DStore().Store()
}

Expand All @@ -586,13 +586,13 @@ func (cfm *CfmApiService) BladesPost(ctx context.Context, applianceId string, cr
if err != nil {
if datastore.DStore().GetDataStore().ContainsBlade(blade.Id, appliance.Id) {

// If blade add fails AND blade in datastore, set it inactive
// If blade add fails AND blade in datastore, set it offline
req := datastore.BladeUpdateRequest{
ApplianceId: appliance.Id,
BladeId: blade.Id,
Status: datastore.Inactive,
Status: common.OFFLINE,
}
datastore.DStore().GetDataStore().UpdateBlade(&req)
datastore.DStore().GetDataStore().UpdateBlade(ctx, &req)
datastore.DStore().Store()
}

Expand All @@ -601,13 +601,13 @@ func (cfm *CfmApiService) BladesPost(ctx context.Context, applianceId string, cr

if datastore.DStore().GetDataStore().ContainsBlade(blade.Id, appliance.Id) {

// If blade add passes AND blade in datastore, set it active
// If blade add passes AND blade in datastore, set it online
req := datastore.BladeUpdateRequest{
ApplianceId: appliance.Id,
BladeId: blade.Id,
Status: datastore.Active,
Status: common.ONLINE,
}
datastore.DStore().GetDataStore().UpdateBlade(&req)
datastore.DStore().GetDataStore().UpdateBlade(ctx, &req)
} else {
// The original need for "credentials" object is fulfilled. Now, reusing this object for DataStore.
datastore.DStore().GetDataStore().AddBlade(&credentials, appliance.Id)
Expand Down Expand Up @@ -652,13 +652,13 @@ func (cfm *CfmApiService) BladesResyncById(ctx context.Context, applianceId stri
if err != nil {
if datastore.DStore().GetDataStore().ContainsBlade(bladeId, applianceId) {

// If blade resync fails AND blade in datastore, just set it inactive
// If blade resync fails AND blade in datastore, just set it offline
req := datastore.BladeUpdateRequest{
ApplianceId: applianceId,
BladeId: bladeId,
Status: datastore.Inactive,
Status: common.OFFLINE,
}
datastore.DStore().GetDataStore().UpdateBlade(&req)
datastore.DStore().GetDataStore().UpdateBlade(ctx, &req)
datastore.DStore().Store()
}

Expand All @@ -667,13 +667,13 @@ func (cfm *CfmApiService) BladesResyncById(ctx context.Context, applianceId stri

if datastore.DStore().GetDataStore().ContainsBlade(bladeId, applianceId) {

// If blade resync pass AND blade in datastore, set it active
// If blade resync pass AND blade in datastore, set it online
req := datastore.BladeUpdateRequest{
ApplianceId: applianceId,
BladeId: bladeId,
Status: datastore.Active,
Status: common.ONLINE,
}
datastore.DStore().GetDataStore().UpdateBlade(&req)
datastore.DStore().GetDataStore().UpdateBlade(ctx, &req)
datastore.DStore().Store()
}

Expand Down Expand Up @@ -749,15 +749,17 @@ func (cfm *CfmApiService) HostsComposeMemory(ctx context.Context, hostId string,
return openapi.Response(http.StatusCreated, memory), nil
}

// HostsDeleteById -
// HostsDeleteById - Guarenteed host deletion from service.
func (cfm *CfmApiService) HostsDeleteById(ctx context.Context, hostId string) (openapi.ImplResponse, error) {
host, err := manager.DeleteHostById(ctx, hostId)
if err != nil {
// Force delete on failure since, currently, manager always removes host from deviceCache, even on failure
datastore.DStore().GetDataStore().DeleteHost(hostId)
datastore.DStore().Store()

return formatErrorResp(ctx, err.(*common.RequestError))
h := openapi.Host{Id: host.Id}

return openapi.Response(http.StatusOK, h), nil
}

datastore.DStore().GetDataStore().DeleteHost(host.Id)
Expand All @@ -767,7 +769,7 @@ func (cfm *CfmApiService) HostsDeleteById(ctx context.Context, hostId string) (o
Id: host.Id,
IpAddress: host.GetNetIp(),
Port: int32(host.GetNetPort()),
Status: "", // Unused
Status: string(host.Status),
Ports: openapi.MemberItem{
Uri: manager.GetCfmUriHostPorts(host.Id),
},
Expand Down Expand Up @@ -820,22 +822,48 @@ func (cfm *CfmApiService) HostsGet(ctx context.Context) (openapi.ImplResponse, e
}

// HostsGetById - Get information for a single CXL Host.
// Note: Do NOT add\delete to\from the datastore here.
func (cfm *CfmApiService) HostsGetById(ctx context.Context, hostId string) (openapi.ImplResponse, error) {
host, err := manager.GetHostById(ctx, hostId)
if err != nil {
if err != nil || host == nil {

// If host get buy id fails AND host in datastore, set it offline
req := datastore.UpdateHostRequest{
HostId: hostId,
Status: common.OFFLINE,
}
datastore.DStore().GetDataStore().UpdateHost(ctx, &req)
datastore.DStore().Store()

return formatErrorResp(ctx, err.(*common.RequestError))
}

totals, err := host.GetMemoryTotals(ctx)
if err != nil {
return formatErrorResp(ctx, err.(*common.RequestError))
// Update datastore status
req := datastore.UpdateHostRequest{
HostId: host.Id,
Status: common.ConnectionStatus(host.Status),
}
datastore.DStore().GetDataStore().UpdateHost(ctx, &req)
datastore.DStore().Store()

var totals *manager.ResponseHostMemoryTotals
if host.Status == common.ONLINE {
totals, err = host.GetMemoryTotals(ctx)
if err != nil {
return formatErrorResp(ctx, err.(*common.RequestError))
}
} else {
totals = &manager.ResponseHostMemoryTotals{
LocalMemoryMib: 0,
RemoteMemoryMib: 0,
}
}

h := openapi.Host{
Id: host.Id,
IpAddress: host.GetNetIp(),
Port: int32(host.GetNetPort()),
Status: "", // Unused
Status: string(host.Status),
Ports: openapi.MemberItem{
Uri: manager.GetCfmUriHostPorts(host.Id),
},
Expand Down Expand Up @@ -967,17 +995,6 @@ func (cfm *CfmApiService) HostsPost(ctx context.Context, credentials openapi.Cre
hosts := manager.GetHosts(ctx)
if len(hosts) >= MAX_COUNT_HOSTS {

if datastore.DStore().GetDataStore().ContainsHost(credentials.CustomId) {

// If host limit exceeded AND host in datastore, set it inactive
req := datastore.HostUpdateRequest{
HostId: credentials.CustomId,
Status: datastore.Inactive,
}
datastore.DStore().GetDataStore().UpdateHost(&req)
datastore.DStore().Store()
}

err := common.RequestError{
StatusCode: common.StatusHostsExceedMaximum,
Err: fmt.Errorf("cfm-service at maximum host capacity (%d)", MAX_COUNT_HOSTS),
Expand All @@ -991,38 +1008,27 @@ func (cfm *CfmApiService) HostsPost(ctx context.Context, credentials openapi.Cre

if datastore.DStore().GetDataStore().ContainsHost(credentials.CustomId) {

// If host add fails AND host in datastore, set it inactive
req := datastore.HostUpdateRequest{
// If host add fails BUT host already in datastore, set pre-existing host offline
req := datastore.UpdateHostRequest{
HostId: credentials.CustomId,
Status: datastore.Inactive,
Status: common.OFFLINE,
}
datastore.DStore().GetDataStore().UpdateHost(&req)
datastore.DStore().GetDataStore().UpdateHost(ctx, &req)
datastore.DStore().Store()
}

return formatErrorResp(ctx, err.(*common.RequestError))
}

if datastore.DStore().GetDataStore().ContainsHost(host.Id) {

// If host add passes AND host in datastore, set it active
req := datastore.HostUpdateRequest{
HostId: host.Id,
Status: datastore.Active,
}
datastore.DStore().GetDataStore().UpdateHost(&req)
} else {
// The original need for "credentials" object is fulfilled. Now, reusing this object for DataStore.
datastore.DStore().GetDataStore().AddHost(&credentials)
}

datastore.DStore().GetDataStore().DeleteHost(host.Id)
datastore.DStore().GetDataStore().AddHost(&credentials)
datastore.DStore().Store()

h := openapi.Host{
Id: host.Id,
IpAddress: host.GetNetIp(),
Port: int32(host.GetNetPort()),
Status: "", // Unused
Status: string(host.Status),
Ports: openapi.MemberItem{
Uri: manager.GetCfmUriHostPorts(host.Id),
},
Expand All @@ -1043,36 +1049,21 @@ func (cfm *CfmApiService) HostsPost(ctx context.Context, credentials openapi.Cre
func (cfm *CfmApiService) HostsResyncById(ctx context.Context, hostId string) (openapi.ImplResponse, error) {
host, err := manager.ResyncHostById(ctx, hostId)
if err != nil {
if datastore.DStore().GetDataStore().ContainsHost(hostId) {

// If host resync fails AND host in datastore, just set it inactive
req := datastore.HostUpdateRequest{
HostId: hostId,
Status: datastore.Inactive,
}
datastore.DStore().GetDataStore().UpdateHost(&req)
datastore.DStore().Store()
}

return formatErrorResp(ctx, err.(*common.RequestError))
}

if datastore.DStore().GetDataStore().ContainsHost(host.Id) {

// If host resync passes AND host in datastore, set it active
req := datastore.HostUpdateRequest{
HostId: host.Id,
Status: datastore.Active,
}
datastore.DStore().GetDataStore().UpdateHost(&req)
datastore.DStore().Store()
req := datastore.UpdateHostRequest{
HostId: host.Id,
Status: common.ConnectionStatus(host.Status),
}
datastore.DStore().GetDataStore().UpdateHost(ctx, &req)
datastore.DStore().Store()

h := openapi.Host{
Id: host.Id,
IpAddress: host.GetNetIp(),
Port: int32(host.GetNetPort()),
Status: "", // Unused
Status: string(host.Status),
Ports: openapi.MemberItem{
Uri: manager.GetCfmUriHostPorts(host.Id),
},
Expand Down
8 changes: 8 additions & 0 deletions pkg/common/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const (
StatusGetMemoryDevicesDetailsFailure //409

StatusApplianceResyncFailure //409
StatusBladeResyncFailure //409
StatusHostResyncFailure //409

StatusApplianceIdDuplicate //409
StatusBladeIdDuplicate //409
Expand Down Expand Up @@ -150,6 +152,10 @@ func (e StatusCodeType) String() string {
return "Get Memory Devices Details Failure"
case StatusApplianceResyncFailure:
return "Appliance Resync Failure"
case StatusBladeResyncFailure:
return "Blade Resync Failure"
case StatusHostResyncFailure:
return "Host Resync Failure"
case StatusBladeIdDoesNotExist:
return "Blade Id Does Not Exist"
case StatusAppliancesExceedMaximum:
Expand Down Expand Up @@ -209,6 +215,8 @@ func (e StatusCodeType) HttpStatusCode() int {
StatusGetMemoryDevicesFailure,
StatusGetMemoryDevicesDetailsFailure,
StatusApplianceResyncFailure,
StatusBladeResyncFailure,
StatusHostResyncFailure,
StatusApplianceIdDuplicate,
StatusBladeIdDuplicate,
StatusPortIdDuplicate,
Expand Down
24 changes: 21 additions & 3 deletions pkg/manager/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
const ID_PREFIX_HOST_DFLT string = "host"

type Host struct {
Id string
Uri string
// Status string // Meaningless without async update
Id string
Uri string
Status common.ConnectionStatus
Socket SocketDetails
Ports map[string]*CxlHostPort
MemoryDevices map[string]*HostMemoryDevice
Expand All @@ -39,6 +39,7 @@ type RequestNewHost struct {
HostId string
Ip string
Port uint16
Status common.ConnectionStatus
BackendOps backend.BackendOperations
Creds *openapi.Credentials
}
Expand All @@ -52,6 +53,7 @@ func NewHost(ctx context.Context, r *RequestNewHost) (*Host, error) {
Uri: GetCfmUriHostId(r.HostId),
Socket: *NewSocketDetails(r.Ip, r.Port),
Ports: make(map[string]*CxlHostPort),
Status: r.Status,
MemoryDevices: make(map[string]*HostMemoryDevice),
Memory: make(map[string]*HostMemory),
backendOps: r.BackendOps,
Expand Down Expand Up @@ -416,6 +418,22 @@ func (h *Host) InvalidateCache() {
}
}

// UpdateConnectionStatusBackend - Query the host root service to verify continued connection and update the object status accordingly.
func (h *Host) UpdateConnectionStatusBackend(ctx context.Context) {
logger := klog.FromContext(ctx)
logger.V(4).Info(">>>>>> GetConnectionsStatusBackend: ", "hostId", h.Id)

req := backend.GetRootServiceRequest{}
response, err := h.backendOps.GetRootService(ctx, &backend.ConfigurationSettings{}, &req)
if err != nil || response == nil {
h.Status = common.OFFLINE
} else {
h.Status = common.ONLINE
}

logger.V(2).Info("update host status(backend)", "status", h.Status, "hostId", h.Id)
}

type ResponseHostMemoryTotals struct {
LocalMemoryMib int32
RemoteMemoryMib int32
Expand Down
Loading

0 comments on commit 6e01adb

Please sign in to comment.