viettel-ffm #19
			
				
			
		
		
		
	| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					package tpl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ENV ...
 | 
				
			||||||
 | 
					type ENV string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						EnvStaging ENV = "STAGING"
 | 
				
			||||||
 | 
						EnvProd    ENV = "PROD"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -1,10 +1,11 @@
 | 
				
			||||||
module git.selly.red/Selly-Modules/3pl
 | 
					module git.selly.red/Selly-Modules/3pl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go 1.17
 | 
					go 1.20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb
 | 
						git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb
 | 
				
			||||||
	git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393
 | 
						git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393
 | 
				
			||||||
 | 
						github.com/go-resty/resty/v2 v2.7.0
 | 
				
			||||||
	github.com/nats-io/nats.go v1.17.0
 | 
						github.com/nats-io/nats.go v1.17.0
 | 
				
			||||||
	github.com/thoas/go-funk v0.9.2
 | 
						github.com/thoas/go-funk v0.9.2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -14,7 +15,6 @@ require (
 | 
				
			||||||
	github.com/elastic/go-licenser v0.4.1 // indirect
 | 
						github.com/elastic/go-licenser v0.4.1 // indirect
 | 
				
			||||||
	github.com/elastic/go-sysinfo v1.1.1 // indirect
 | 
						github.com/elastic/go-sysinfo v1.1.1 // indirect
 | 
				
			||||||
	github.com/elastic/go-windows v1.0.1 // indirect
 | 
						github.com/elastic/go-windows v1.0.1 // indirect
 | 
				
			||||||
	github.com/go-resty/resty/v2 v2.7.0 // indirect
 | 
					 | 
				
			||||||
	github.com/golang/snappy v0.0.3 // indirect
 | 
						github.com/golang/snappy v0.0.3 // indirect
 | 
				
			||||||
	github.com/jcchavezs/porto v0.4.0 // indirect
 | 
						github.com/jcchavezs/porto v0.4.0 // indirect
 | 
				
			||||||
	github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
 | 
						github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										4
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -1,9 +1,5 @@
 | 
				
			||||||
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb h1:AmcYd88IcdSkH+NEvKyJLT7psidSkjJQT/nAg/KuzFk=
 | 
					git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb h1:AmcYd88IcdSkH+NEvKyJLT7psidSkjJQT/nAg/KuzFk=
 | 
				
			||||||
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb/go.mod h1:Q1//Z6HRmfa7VyjH2J6YyT0YV2jT8+K6SIgwnYuS4II=
 | 
					git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb/go.mod h1:Q1//Z6HRmfa7VyjH2J6YyT0YV2jT8+K6SIgwnYuS4II=
 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.2-0.20221010041139-c11419a3ad33 h1:GvQjelaV4XZm++AOihYAKOD6k9510aMAr6B6MGnrXPs=
 | 
					 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.2-0.20221010041139-c11419a3ad33/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
 | 
					 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231006093940-b3bde5cd0960 h1:wL/BW1xGoB/EXeA2HtxT6Nr/cXpPJYVNfToV3aFtGls=
 | 
					 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231006093940-b3bde5cd0960/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
 | 
					 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393 h1:43kE03FW3NONfE6hXlghafS1d233dfc7grlFqd+15SA=
 | 
					git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393 h1:43kE03FW3NONfE6hXlghafS1d233dfc7grlFqd+15SA=
 | 
				
			||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
 | 
					git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
 | 
				
			||||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
 | 
					github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					package viettelffm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AuthRes struct {
 | 
				
			||||||
 | 
						AccessToken      string `json:"access_token"`
 | 
				
			||||||
 | 
						ExpiresIn        int    `json:"expires_in"`
 | 
				
			||||||
 | 
						RefreshExpiresIn int    `json:"refresh_expires_in"`
 | 
				
			||||||
 | 
						RefreshToken     string `json:"refresh_token"`
 | 
				
			||||||
 | 
						TokenType        string `json:"token_type"`
 | 
				
			||||||
 | 
						NotBeforePolicy  int    `json:"not-before-policy"`
 | 
				
			||||||
 | 
						SessionState     string `json:"session_state"`
 | 
				
			||||||
 | 
						Scope            string `json:"scope"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateLogisticInfoPayload struct {
 | 
				
			||||||
 | 
						PrintLabelLink string `json:"print_label_link"`
 | 
				
			||||||
 | 
						TrackingCode   string `json:"tracking_code"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ORPayload struct {
 | 
				
			||||||
 | 
						OrProductLines []ORProductLine `json:"or_product_lines"`
 | 
				
			||||||
 | 
						AmountPaid     float64         `json:"amount_paid"`
 | 
				
			||||||
 | 
						CodAmount      float64         `json:"cod_amount"`
 | 
				
			||||||
 | 
						CodType        string          `json:"cod_type"`
 | 
				
			||||||
 | 
						Note           string          `json:"note"`
 | 
				
			||||||
 | 
						OrCode         string          `json:"or_code"`
 | 
				
			||||||
 | 
						OrType         string          `json:"or_type"`
 | 
				
			||||||
 | 
						ShippingType   string          `json:"shipping_type"`
 | 
				
			||||||
 | 
						CustomerName   string          `json:"customer_name"`
 | 
				
			||||||
 | 
						CustomerEmail  string          `json:"customer_email"`
 | 
				
			||||||
 | 
						PackType       string          `json:"pack_type"`
 | 
				
			||||||
 | 
						PriorityType   string          `json:"priority_type"`
 | 
				
			||||||
 | 
						Warehouse      ORWarehouse     `json:"warehouse"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ORProductLine struct {
 | 
				
			||||||
 | 
						Discount             float64              `json:"discount"`
 | 
				
			||||||
 | 
						Price                float64              `json:"price"`
 | 
				
			||||||
 | 
						Product              Product              `json:"product"`
 | 
				
			||||||
 | 
						Quantity             int                  `json:"quantity"`
 | 
				
			||||||
 | 
						SpecifiedProductLine SpecifiedProductLine `json:"specified_product_line"`
 | 
				
			||||||
 | 
						Unit                 string               `json:"unit"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SpecifiedProductLine struct {
 | 
				
			||||||
 | 
						ProductConditionType ProdCondType `json:"product_condition_type"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Product struct {
 | 
				
			||||||
 | 
						PartnerSku string `json:"partner_sku"`
 | 
				
			||||||
 | 
						ProductId  int    `json:"product_id"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProdCondType struct {
 | 
				
			||||||
 | 
						Name string `json:"name"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ORWarehouse struct {
 | 
				
			||||||
 | 
						WarehouseId int `json:"warehouse_id"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ORResult struct {
 | 
				
			||||||
 | 
						OrCode string `json:"or_code"`
 | 
				
			||||||
 | 
						OrId   int    `json:"or_id"`
 | 
				
			||||||
 | 
						Status string `json:"status"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,201 @@
 | 
				
			||||||
 | 
					package viettelffm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.selly.red/Selly-Modules/natsio"
 | 
				
			||||||
 | 
						"git.selly.red/Selly-Modules/natsio/model"
 | 
				
			||||||
 | 
						"git.selly.red/Selly-Modules/natsio/subject"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tpl "git.selly.red/Selly-Modules/3pl"
 | 
				
			||||||
 | 
						"git.selly.red/Selly-Modules/3pl/util/httputil"
 | 
				
			||||||
 | 
						"git.selly.red/Selly-Modules/3pl/util/pjson"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						baseURLStag     = "https://stg-gw.viettelpost.vn"
 | 
				
			||||||
 | 
						baseURLAuthStag = "https://stg-keycloak.viettelpost.vn"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: update prod url
 | 
				
			||||||
 | 
						baseURLProd     = ""
 | 
				
			||||||
 | 
						baseURLAuthProd = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pathAuth                 = "/realms/wms/protocol/openid-connect/token"
 | 
				
			||||||
 | 
						pathUpdateORLogisticInfo = "/wms-core/api/v1/obms/outbound-request/outbound-request-partner/%s/bill"
 | 
				
			||||||
 | 
						pathCreateOR             = "/wms-core/api/v1/obms/outbound-request/outbound-request-partner"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logTarget = "viettel-ffm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						baseURLENVMapping = map[tpl.ENV]string{
 | 
				
			||||||
 | 
							tpl.EnvProd:    baseURLProd,
 | 
				
			||||||
 | 
							tpl.EnvStaging: baseURLStag,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Client struct {
 | 
				
			||||||
 | 
						env      tpl.ENV
 | 
				
			||||||
 | 
						username string
 | 
				
			||||||
 | 
						password string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						natsClient          natsio.Server
 | 
				
			||||||
 | 
						authInfo            *AuthRes
 | 
				
			||||||
 | 
						authTokenExpireTime time.Time
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewClient generate OnPoint client
 | 
				
			||||||
 | 
					func NewClient(env tpl.ENV, user, pwd string, nc natsio.Server) (*Client, error) {
 | 
				
			||||||
 | 
						if user == "" || pwd == "" {
 | 
				
			||||||
 | 
							return nil, errors.New("viettelffm: cannot init with empty api key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &Client{
 | 
				
			||||||
 | 
							env:        env,
 | 
				
			||||||
 | 
							username:   user,
 | 
				
			||||||
 | 
							password:   pwd,
 | 
				
			||||||
 | 
							natsClient: nc,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) CreateOR(p ORPayload) (*ORResult, error) {
 | 
				
			||||||
 | 
						apiURL := c.getBaseURL() + pathCreateOR
 | 
				
			||||||
 | 
						token, err := c.getToken()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						natsPayload := model.CommunicationRequestHttp{
 | 
				
			||||||
 | 
							ResponseImmediately: true,
 | 
				
			||||||
 | 
							Payload: model.HttpRequest{
 | 
				
			||||||
 | 
								URL:    apiURL,
 | 
				
			||||||
 | 
								Method: http.MethodPost,
 | 
				
			||||||
 | 
								Data:   pjson.ToJSONString(p),
 | 
				
			||||||
 | 
								Header: map[string]string{
 | 
				
			||||||
 | 
									httputil.HeaderKeyAuthorization: fmt.Sprintf("Bearer %s", token),
 | 
				
			||||||
 | 
									httputil.HeaderKeyContentType:   httputil.HeaderValueApplicationJSON,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LogTarget: logTarget,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r, err := c.requestHttpViaNats(natsPayload)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.CreateOR - requestHttpViaNats %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res := r.Response
 | 
				
			||||||
 | 
						if res.StatusCode >= http.StatusBadRequest {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.CreateOR - requestHttpViaNats %s", res.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var data ORResult
 | 
				
			||||||
 | 
						if err = r.ParseResponseData(&data); err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.CreateOR - requestHttpViaNats parse response %v, %s", err, res.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &data, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) UpdateOutboundRequestLogisticInfo(p UpdateLogisticInfoPayload) error {
 | 
				
			||||||
 | 
						apiURL := c.getBaseURL() + pathUpdateORLogisticInfo
 | 
				
			||||||
 | 
						token, err := c.getToken()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						natsPayload := model.CommunicationRequestHttp{
 | 
				
			||||||
 | 
							ResponseImmediately: true,
 | 
				
			||||||
 | 
							Payload: model.HttpRequest{
 | 
				
			||||||
 | 
								URL:    apiURL,
 | 
				
			||||||
 | 
								Method: http.MethodPost,
 | 
				
			||||||
 | 
								Data:   pjson.ToJSONString(p),
 | 
				
			||||||
 | 
								Header: map[string]string{
 | 
				
			||||||
 | 
									httputil.HeaderKeyAuthorization: fmt.Sprintf("Bearer %s", token),
 | 
				
			||||||
 | 
									httputil.HeaderKeyContentType:   httputil.HeaderValueApplicationJSON,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LogTarget: logTarget,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r, err := c.requestHttpViaNats(natsPayload)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res := r.Response
 | 
				
			||||||
 | 
						if res.StatusCode >= http.StatusBadRequest {
 | 
				
			||||||
 | 
							return fmt.Errorf("viettelffm.Client.UpdateOutboundRequestLogisticInfo - requestHttpViaNats %s", res.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Auth ...
 | 
				
			||||||
 | 
					func (c *Client) Auth() (*AuthRes, error) {
 | 
				
			||||||
 | 
						v := url.Values{}
 | 
				
			||||||
 | 
						v.Set("username", c.username)
 | 
				
			||||||
 | 
						v.Set("password", c.password)
 | 
				
			||||||
 | 
						v.Set("grant_type", "password")
 | 
				
			||||||
 | 
						v.Set("client_id", "wms_account")
 | 
				
			||||||
 | 
						b := v.Encode()
 | 
				
			||||||
 | 
						header := map[string]string{
 | 
				
			||||||
 | 
							httputil.HeaderKeyContentType: httputil.HeaderValueApplicationURLEncoded,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						bURL := baseURLAuthStag
 | 
				
			||||||
 | 
						if c.env == tpl.EnvProd {
 | 
				
			||||||
 | 
							bURL = baseURLAuthProd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						api := bURL + pathAuth
 | 
				
			||||||
 | 
						natsPayload := model.CommunicationRequestHttp{
 | 
				
			||||||
 | 
							ResponseImmediately: true,
 | 
				
			||||||
 | 
							Payload: model.HttpRequest{
 | 
				
			||||||
 | 
								URL:    api,
 | 
				
			||||||
 | 
								Method: http.MethodPost,
 | 
				
			||||||
 | 
								Data:   b,
 | 
				
			||||||
 | 
								Header: header,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LogTarget: logTarget,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r, err := c.requestHttpViaNats(natsPayload)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.Auth - requestHttpViaNats: payload %+v, err %v\n", natsPayload, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res := r.Response
 | 
				
			||||||
 | 
						if res.StatusCode >= http.StatusBadRequest {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.Auth - requestHttpViaNats %s", res.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var data AuthRes
 | 
				
			||||||
 | 
						if err = r.ParseResponseData(&data); err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.Auth - requestHttpViaNats parse response %v, %s", err, res.Body)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &data, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) getToken() (string, error) {
 | 
				
			||||||
 | 
						if c.authInfo == nil || time.Now().After(c.authTokenExpireTime) {
 | 
				
			||||||
 | 
							auth, err := c.Auth()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return "", err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							c.authInfo = auth
 | 
				
			||||||
 | 
							c.authTokenExpireTime = time.Now().Add(time.Duration(auth.ExpiresIn) * time.Second).Add(-time.Minute)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c.authInfo.AccessToken, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) getBaseURL() string {
 | 
				
			||||||
 | 
						return baseURLENVMapping[c.env]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp) (*model.CommunicationHttpResponse, error) {
 | 
				
			||||||
 | 
						b := pjson.ToBytes(data)
 | 
				
			||||||
 | 
						msg, err := c.natsClient.Request(subject.Communication.RequestHTTP, b)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.requestHttpViaNats err: %v, url %s", err, data.Payload.URL)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var r model.CommunicationHttpResponse
 | 
				
			||||||
 | 
						if err = pjson.Unmarshal(msg.Data, &r); err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.requestHttpViaNats parse data err: %v, url %s, data %s", err, data.Payload.URL, string(msg.Data))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if r.Response == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("viettelffm.Client.requestHttpViaNats empty reponse")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &r, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
package httputil
 | 
					package httputil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	HeaderKeyContentType = "Content-Type"
 | 
						HeaderKeyContentType   = "Content-Type"
 | 
				
			||||||
 | 
						HeaderKeyAuthorization = "Authorization"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	HeaderValueApplicationJSON       = "application/json"
 | 
						HeaderValueApplicationJSON       = "application/json"
 | 
				
			||||||
	HeaderValueApplicationURLEncoded = "application/x-www-form-urlencoded"
 | 
						HeaderValueApplicationURLEncoded = "application/x-www-form-urlencoded"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue