部署到 AD 时 Azure 函数未成功执行

问题描述 投票:0回答:1

我在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"
  }
 ]
}
go azure-functions
1个回答
0
投票

尝试为 Linux amd64 编译您的应用程序。

假设你的 go 文件名为“Muaaz.go”

GOOS=linux GOARCH=amd64 go build Muaaz.go

另外,使用 Linux 可执行文件名称更新你的 host.json

... host.json 
    "defaultExecutablePath": "Muaaz",
...

参考:https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-vs-code-other?tabs=go#compile-the-custom-handler-for-天蓝色

交叉编译并更新您的 host.json 后,重新发布到您的 azure 帐户。

如果仍然收到 5xx 错误,请检查日志以查看是否有任何有用的日志消息。

© www.soinside.com 2019 - 2024. All rights reserved.