func (g *GoBgpFlowSpecReceiver) RegisterProtection(r *MitigationOrDataChannelACL, targetID int64, customerID int, targetType string) (p Protection, err error) {
	droppedStatus := NewProtectionStatus(
		0, 0, 0, 0, 0,
	)
	var aclName string
	if r.DataChannelACL != nil {
		aclName = r.DataChannelACL.Name
	} else {
		aclName = r.MitigationRequest.AclName
	}
	base := ProtectionBase{
		0,
		customerID,
		targetID,
		targetType,
		aclName,
		"",
		"",
		g,
		false,
		time.Unix(0, 0),
		time.Unix(0, 0),
		time.Unix(0, 0),
		droppedStatus,
	}
	log.Debugf("stored external storage.  %+v", base)
	var flowSpecTargets []FlowSpecTarget
	if r.DataChannelACL != nil {
		flowSpecTargets, err = CreateFlowSpecTargetsForDataChannelACL(r.DataChannelACL)
	} else {
		flowSpecTargets, err = CreateFlowSpecTargetsForMitigation(r.MitigationRequest, g.vrf)
	}
	if err != nil { return }
	p = &FlowSpec{ base, flowSpecTargets }
	dbP, err := CreateProtection2(p)
	if err != nil {
		return
	}
	return GetProtectionById(dbP.Id)
}
/*
Register protection with flow spec is mititgation request or data channel acl

parameter:
r the mitigation request or the data channel acl
targetID the target_id of protection
customerID the Id of Customer
targetType the target_type of protection
return:
p the new protection
err error
package models
import (
	"time"
	"net"
	"strconv"
	"strings"
	"errors"
	"encoding/json"
	"context"
	"github.com/nttdots/go-dots/dots_server/db_models"
	log "github.com/sirupsen/logrus"
	types "github.com/nttdots/go-dots/dots_common/types/data"
	"github.com/osrg/gobgp/pkg/packet/bgp"
	"google.golang.org/grpc"
	"github.com/golang/protobuf/ptypes"
	"github.com/golang/protobuf/ptypes/any"
	"github.com/golang/protobuf/proto"
	api "github.com/osrg/gobgp/api"
)
const (
	FLOWSPEC_BLOCKER_HOST    = "host"
	FLOWSPEC_BLOCKER_PORT    = "port"
	FLOWSPEC_BLOCKER_TIMEOUT = "timeout"
	FLOWSPEC_BLOCKER_NEXTHOP = "nextHop"
	FLOWSPEC_BLOCKER_VRF     = "vrf"
)
const (
	BLOCKER_TYPE_GoBGP_FLOWSPEC = "GoBGP-FlowSpec"
	PROTECTION_TYPE_FLOWSPEC    = "FlowSpec"
	IPV4_FLOW_SPEC          = "ipv4-flowspec"
	IPV6_FLOW_SPEC          = "ipv6-flowspec"
	ACTION_TYPE_DISCARD     = "discard"
	ACTION_TYPE_ACCEPT      = "accept"
	ACTION_TYPE_RATE_LIMIT  = "rate-limit"
	ACTION_TYPE_REDIRECT    = "redirect"
)
var (
	ipv4UC = &api.Family{
		Afi:  api.Family_AFI_IP,
		Safi: api.Family_SAFI_FLOW_SPEC_UNICAST,
	}
	ipv6UC = &api.Family{
		Afi:  api.Family_AFI_IP6,
		Safi: api.Family_SAFI_FLOW_SPEC_UNICAST,
	}
)
type FlowspecPort struct {
	LowerPort   *int     `json:"lower-port"`
	UpperPort   *int     `json:"upper-port"`
	Operator    *uint8   `json:"operator"`
	Port        *int     `json:"port"`
}
type FlowspecICMPType struct {
	LowerType   *int     `json:"lower-type"`
	UpperType   *int     `json:"upper-type"`
}
type FlowspecBitmask struct {
	Bitmask    uint8   `json:"bitmask"`
	Flag       int     `json:"flag"`
}
type FlowSpecMapping struct {
	DestinationPrefix        string            `json:"destination"`
	SourcePrefix             string            `json:"source"`
	Protocol                 []int             `json:"protocol"`
	Port                     []FlowspecPort    `json:"port"`
	DestinationPort          []FlowspecPort    `json:"destination-port"`
	SourcePort               []FlowspecPort    `json:"source-port"`
	ImcpType                 []FlowspecICMPType `json:"imcp-type"`
	ImcpCode                 *int              `json:"imcp-code"`
	TcpFlags                 []FlowspecBitmask `json:"tcp-flags"`
	PacketLength             *int              `json:"packet-length"`
	Dscp                     *int              `json:"dscp"`
	Fragment                 *FlowspecBitmask  `json:"fragment"`
	FlowLabel                *int              `json:"label"`
	TrafficActionType        string            `json:"action_type"`
	TrafficActionValue       string            `json:"action_value"`
	FlowType                 string            `json:"flow-type"`
}
type FlowSpec struct {
	ProtectionBase
	flowSpecTargets  []FlowSpecTarget
}
type FlowSpecTarget struct {
	flowType string
	flowSpec []byte
}
type GoBgpFlowSpecReceiver struct {
	BlockerBase
	host    string
	port    string
	timeout int
	nextHop string
	vrf     string
}
func (f *FlowSpecMapping) FromDB(data []byte) error {
	return json.Unmarshal(data, f)
}
func (f *FlowSpecMapping) ToDB() ([]byte, error) {
	return json.Marshal(f)
}
func (f *FlowSpecMapping) String() (string) {
	res, _ := json.Marshal(f)
	return string(res)
}
func (g *FlowSpec) FlowSpecTargets() []FlowSpecTarget {
	return g.flowSpecTargets
}
func (flow *FlowSpecTarget) FlowType() string {
	return flow.flowType
}
func (flow *FlowSpecTarget) FlowSpec() []byte {
	return flow.flowSpec
}
func (flow *FlowSpecTarget) String() string {
	return string(flow.flowSpec)
}
func (g *GoBgpFlowSpecReceiver) Connect() (err error) {
	return
}
func (g *GoBgpFlowSpecReceiver) GenerateProtectionCommand(m *MitigationScope) (c string, err error) {
	c = EMPTY_VALUE
	return
}
func NewGoBgpFlowSpecReceiver(base BlockerBase, params map[string][]string, configParams map[string][]string) *GoBgpFlowSpecReceiver {
	var host string
	var port string
	var timeout int
	var nextHop string
	var vrf  string
	a, ok := params[FLOWSPEC_BLOCKER_HOST]
	if ok {
		host = a[0]
	} else {
		host = ""
	}
	a, ok = params[FLOWSPEC_BLOCKER_PORT]
	if ok {
		port = a[0]
	} else {
		port = ""
	}
	a, ok = params[FLOWSPEC_BLOCKER_TIMEOUT]
	if ok {
		timeout, _ = strconv.Atoi(a[0])
	} else {
		timeout = 0
	}
	a, ok = params[FLOWSPEC_BLOCKER_NEXTHOP]
	if ok {
		nextHop = a[0]
	} else {
		nextHop = ""
	}
	a, ok = configParams[FLOWSPEC_BLOCKER_VRF]
	if ok {
		vrf = a[0]
	} else {
		vrf = ""
	}
	return &GoBgpFlowSpecReceiver{
		base,
		host,
		port,
		timeout,
		nextHop,
		vrf,
	}
}
func (g *GoBgpFlowSpecReceiver) Type() BlockerType {
	return BLOCKER_TYPE_GoBGP_FLOWSPEC
}
func (g FlowSpec) Type() ProtectionType {
	return PROTECTION_TYPE_FLOWSPEC
}
func (g *GoBgpFlowSpecReceiver) ExecuteProtection(p Protection) (err error) {
	t, ok := p.(*FlowSpec)
	if !ok {
		log.Warnf("GoBgpFlowSpecReceiver::ExecuteProtection protection type error. %T", p)
		err = errors.New("Protection type error")
		return
	}
	log.Info("GoBgpFlowSpecReceiver.ExecuteProtection")
	blockerClient, conn, err := g.connect()
	if err != nil {
		return err
	}
	log.Infof("gobgp client connect[%p]", blockerClient)
	defer func(){
		log.Info("gobgp client close")
		conn.Close()
	}()
	paths, err := g.toPath(t)
	if err != nil {
		return err
	}
	for _, path := range paths {
		_, err = blockerClient.AddPath(context.Background(),&api.AddPathRequest{
			TableType: api.TableType_GLOBAL,
			VrfId:    "",
			Path:     path,
		})
		if err != nil {
			return err
		}
	}
	err = StartProtection(p, g)
	if err != nil {
		return err
	}
	return
}
func (g *GoBgpFlowSpecReceiver) StopProtection(p Protection) (err error) {
	t, ok := p.(*FlowSpec)
	if !ok {
		log.Warnf("GoBgpFlowSpecReceiver::StopProtection protection type error. %T", p)
		err = errors.New("Protection type error")
		return
	}
	if !t.isEnabled {
		log.Warnf("GoBgpFlowSpecReceiver::StopProtection protection not started. %+v", p)
		err = errors.New("Protection not started")
		return
	}
	log.WithFields(log.Fields{
		"target_id":   t.TargetId(),
		"target_type": t.TargetType(),
		"load":        g.Load(),
	}).Infof("GoBgpFlowSpecReceiver.StopProtection")
	blockerClient, conn, err := g.connect()
	if err != nil {
		return err
	}
	log.Infof("gobgp client connect[%p]", blockerClient)
	defer func(){
		log.Info("gobgp client close")
		conn.Close()
	}()
	paths, err := g.toPath(t)
	if err != nil { return err }
	for _, path := range paths {
		_, err = blockerClient.DeletePath(context.Background(),&api.DeletePathRequest{
			TableType: api.TableType_GLOBAL,
			VrfId:    "",
			Path:     path,
		})
		if err != nil { return err }
	}
	err = StopProtection(p, g)
	if err != nil {
		return
	}
	return
}
 func (g *GoBgpFlowSpecReceiver) connect() (bgpClient api.GobgpApiClient, conn *grpc.ClientConn ,err error) {
	return connect(g.timeout, g.host, g.port)
}
func (g *GoBgpFlowSpecReceiver) toPath(b *FlowSpec) ([]*api.Path, error) {
	attrs := []bgp.PathAttributeInterface {
		bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP),
		bgp.NewPathAttributeNextHop(g.nextHop),
	}
	paths := make([]*api.Path, 0)
	t, _ := ptypes.TimestampProto(time.Now())
	var flowspecMapping FlowSpecMapping
	for _, flowspec := range b.flowSpecTargets {
		var family *api.Family
		if flowspec.flowType == IPV4_FLOW_SPEC {
			family = ipv4UC
		} else if flowspec.flowType == IPV6_FLOW_SPEC {
			family = ipv6UC
		}
		err := flowspecMapping.FromDB(flowspec.flowSpec)
		if err != nil {
			log.Errorf("Parse DB json to mapping object failed, error: %+v", err)
			return nil, err
		}
		prefixInterface, err := flowspecMapping.CreateFlowSpec()
		if err != nil {
			log.Errorf("Create GoBGP Flowspec NLRI failed.")
			return nil, err
		}
		extAttr, err := flowspecMapping.CreateExtendedCommunities()
		if err != nil {
			log.Errorf("Create Extended Communities Flowspec failed.")
			return nil, err	
		}
		anyNrli := MarshalNLRI(prefixInterface)
		anyPattrs := MarshalPathAttributes(append(attrs, extAttr))
		p := &api.Path {
			Nlri:               anyNrli,
			Pattrs:             anyPattrs,
			Age:                t,
			IsWithdraw:         false,
			Family:             family,
			Identifier:         prefixInterface.PathIdentifier(),
			LocalIdentifier:    prefixInterface.PathLocalIdentifier(),
		}
		paths = append(paths, p)
	}
	return paths, nil
}