我在golang中编写了一个azure函数来获取azure存储帐户的内容,然后将数据发送到另一个服务,它在本地运行良好,但是当我将其部署到AD时,它不断给出500内部服务器错误 这是代码
package main
import (
"bytes"
"context"
"encoding/csv"
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
)
func handleError(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
func get_Port() string {
port := ":8000"
if val, ok := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT"); ok {
port = ":" + val
}
return port
}
func handleFunc() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.Header().Set("Access-Control-Allow-Origin", "https://portal.azure.com.")
postFunc()
c.JSON(http.StatusOK, gin.H{
"body": "body",
})
}
}
func main() {
router := gin.Default()
router.GET("/api/Ziyad", handleFunc())
port := get_Port()
router.Run(port)
}
func postFunc() {
err := godotenv.Load()
if err != nil {
log.Println("Error: could not load godotenv")
}
fmt.Printf("Azure Blob storage quick start sample\n")
url := "https://{mystorageaccountname}.blob.core.windows.net/"
ctx := context.Background()
credential, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
log.Fatalln("Error : Could not get credential from azure identity")
}
client, err := azblob.NewClient(url, credential, nil)
if err != nil {
log.Fatalln("Error : could not get new client from azure blob")
}
fmt.Println("Listing the blobs in the container:")
containerName := "bcfolder"
blobName := "Book1.csv"
blobDownloadResp, err := client.DownloadStream(ctx, containerName, blobName, nil)
if err != nil {
log.Fatalln("Error : could not download stream from client")
}
defer blobDownloadResp.Body.Close()
reader := blobDownloadResp.Body
downloadedData, err := io.ReadAll(reader)
if err != nil {
log.Fatalln("Error : could not read the downloaded stream body")
}
csvData := csv.NewReader(bytes.NewBuffer(downloadedData))
_, err1 := csvData.Read() // skip first line
if err1 != nil {
if err1 != io.EOF {
log.Fatalln(err1)
return
}
}
for {
line, err := csvData.Read()
if err != nil {
if err == io.EOF {
break
}
}
data := fmt.Sprintf(`{"jsontext":"{\"No\":\"%s\",\"desc\":\"%s\",\"UOM\":\"%s\",\"cost\":\"%s\",\"price\":\"%s\"}"}`,
line[0], line[1], line[2], line[3], line[4])
fmt.Printf("%s\n", data)
payload := bytes.NewBuffer([]byte(data))
postToBC(payload)
break
}
}
func get_access_token() (accessToken string) {
err := godotenv.Load()
handleError(err)
client_Id := os.Getenv("client_id")
client_Secret := os.Getenv("client_secret")
tenantID := os.Getenv("tenantID")
cred, err := confidential.NewCredFromSecret(client_Secret)
if err != nil {
log.Fatalln("Error while getting the credential", err)
}
confidentialClient, err :=
confidential.New("https://login.microsoftonline.com/"+tenantID, client_Id, cred)
scopes := []string{"https://api.businesscentral.dynamics.com/.default"}
result, err := confidentialClient.AcquireTokenSilent(context.TODO(), scopes)
if err != nil {
// cache miss, authenticate with another AcquireToken... method
result, err = confidentialClient.AcquireTokenByCredential(context.TODO(), scopes)
if err != nil {
log.Fatalln("Error while acquiring the token", err)
}
}
accessToken = result.AccessToken
return
}
func postToBC(payload io.Reader) {
url := "https://api.businesscentral.dynamics.com/v2.0/" + os.Getenv("tenantID") +
"/sandbox2/ODataV4/MyWebService_InsertItemFromJson?company=Xeetek"
method := "POST"
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer "+get_access_token())
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
当我在本地运行 azure 函数时,它工作正常,但是当我部署并尝试运行它时,它需要很长时间并给出 500 内部错误 这是 local.settings.json
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "custom",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}
}
这是host.json
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"customHandler": {
"enableForwardingHttpRequest":true,
"description": {
"defaultExecutablePath": "Muaaz.exe",
"workingDirectory": "",
"arguments": []
}
}
}
这是 function.json
{
"bindings": [
{
"authLevel": "Anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
],
"route":"Ziyad"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
尝试为 Linux amd64 编译您的应用程序。
假设你的 go 文件名为“Muaaz.go”
GOOS=linux GOARCH=amd64 go build Muaaz.go
另外,使用 Linux 可执行文件名称更新你的 host.json
... host.json
"defaultExecutablePath": "Muaaz",
...
交叉编译并更新您的 host.json 后,重新发布到您的 azure 帐户。
如果仍然收到 5xx 错误,请检查日志以查看是否有任何有用的日志消息。