| /* |
| * Copyright 2022-present Open Networking Foundation |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package onosnbi |
| |
| import ( |
| "context" |
| "encoding/json" |
| "net/http" |
| "strconv" |
| |
| cntlr "voltha-go-controller/internal/pkg/controller" |
| errorCodes "voltha-go-controller/internal/pkg/errorcodes" |
| "voltha-go-controller/internal/pkg/of" |
| "voltha-go-controller/log" |
| |
| "github.com/gorilla/mux" |
| ) |
| |
| // FlowHandle struct to handle flow related REST calls |
| type FlowHandle struct { |
| } |
| |
| // FlowHandle struct to handle flow related REST calls |
| type PendingFlowHandle struct { |
| } |
| |
| type TrafficSelector struct { |
| } |
| |
| type TrafficTreatment struct { |
| } |
| |
| /* |
| type FlowEntry struct { |
| TrafficSelector |
| TrafficTreatment |
| FlowID int |
| AppID int |
| GroupID int |
| Priority int |
| DeviceID string |
| TimeOut int |
| TableID int |
| }*/ |
| |
| func (fh *FlowHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL}) |
| switch r.Method { |
| case cGet: |
| fh.GetFlows(context.Background(), w, r) |
| default: |
| logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method}) |
| err := errorCodes.ErrOperationNotSupported |
| http.Error(w, err.Error(), http.StatusBadRequest) |
| } |
| } |
| |
| func (pfh *PendingFlowHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL}) |
| switch r.Method { |
| case cGet: |
| pfh.GetPendingFlows(context.Background(), w, r) |
| default: |
| logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method}) |
| err := errorCodes.ErrOperationNotSupported |
| http.Error(w, err.Error(), http.StatusBadRequest) |
| } |
| } |
| |
| func (pfh *PendingFlowHandle) GetPendingFlows(cntx context.Context, w http.ResponseWriter, r *http.Request) { |
| logger.Debug(ctx, "Received Get Pending Flows request") |
| |
| flows, err := cntlr.GetController().GetAllPendingFlows() |
| if err != nil { |
| logger.Errorw(ctx, "Failed to get Pending flows", log.Fields{"Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| flowResp := ConvertFlowsToFlowEntry(flows) |
| FlowRespJSON, err := json.Marshal(flowResp) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to marshal pending flow response", log.Fields{"Flows": flows, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| |
| w.Header().Add("Content-Type", "application/json") |
| _, err = w.Write(FlowRespJSON) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to write Pending Flow response", log.Fields{"Flows": flows, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| } |
| } |
| |
| func (fh *FlowHandle) GetFlows(cntx context.Context, w http.ResponseWriter, r *http.Request) { |
| vars := mux.Vars(r) |
| deviceID := vars["deviceId"] |
| flowIDStr := vars["flowId"] |
| var flowID uint64 |
| var parseErr error |
| |
| logger.Debugw(ctx, "Received Get Flows specific to flowID and deviceID", log.Fields{"flowId": flowIDStr, "DeviceID": deviceID}) |
| if len(flowIDStr) > 0 { |
| flowID, parseErr = strconv.ParseUint(flowIDStr, 10, 64) |
| if parseErr != nil { |
| logger.Errorw(ctx, "Failed to parse flowIDStr from string to uint64", log.Fields{"flowIDStr": flowIDStr, "Reason": parseErr.Error()}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| } |
| |
| var flowResp FlowEntry |
| if len(deviceID) > 0 && len(flowIDStr) > 0 { |
| flow, err := fh.getFlow(deviceID, flowID) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to Fetch flow", log.Fields{"FlowID": flowID, "DeviceID": deviceID, "Error": err}) |
| http.Error(w, err.Error(), http.StatusBadRequest) |
| return |
| } |
| flowResp = ConvertFlowToFlowEntry(flow) |
| // flowResp = append(flowResp, flow) |
| } else { |
| flows, err := fh.getAllFlows(deviceID) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to Fetch flows", log.Fields{"DeviceID": deviceID, "Error": err}) |
| http.Error(w, err.Error(), http.StatusBadRequest) |
| return |
| } |
| flowResp = ConvertFlowsToFlowEntry(flows) |
| // ..flowResp = append(flowResp, flows...) |
| } |
| FlowRespJSON, err := json.Marshal(flowResp) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to marshal flow response", log.Fields{"FlowID": flowID, "DeviceID": deviceID, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| |
| w.Header().Add("Content-Type", "application/json") |
| _, err = w.Write(FlowRespJSON) |
| if err != nil { |
| logger.Errorw(ctx, "Failed to write flow response", log.Fields{"FlowID": flowID, "DeviceID": deviceID, "Error": err}) |
| w.WriteHeader(http.StatusInternalServerError) |
| return |
| } |
| logger.Debugw(ctx, "Request for getting Flow specific to flowID and deviceID", log.Fields{"FlowID": flowID, "DeviceID": deviceID, "flowResp": flowResp}) |
| } |
| |
| func (fh *FlowHandle) getAllFlows(deviceID string) ([]*of.VoltSubFlow, error) { |
| if len(deviceID) == 0 { |
| return cntlr.GetController().GetAllFlows() |
| } |
| return cntlr.GetController().GetFlows(deviceID) |
| } |
| |
| func (fh *FlowHandle) getFlow(deviceID string, flowID uint64) (*of.VoltSubFlow, error) { |
| return cntlr.GetController().GetFlow(deviceID, flowID) |
| } |