<commit_before>// Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
//	http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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.

//Handlers for V1

package handlers

import (
	"encoding/json"
	"github.com/aws/amazon-ecs-agent/agent/api"
	"github.com/aws/amazon-ecs-agent/agent/config"
	"github.com/aws/amazon-ecs-agent/agent/engine"
	"github.com/aws/amazon-ecs-agent/agent/engine/dockerstate"
	"github.com/aws/amazon-ecs-agent/agent/logger"
	"net/http"
	"strconv"
	"time"
)

var log = logger.ForModule("Handlers")

const statusBadRequest = 400
const statusNotImplemented = 501
const statusOK = 200

type RootResponse struct {
	AvailableCommands []string
}

func MetadataV1RequestHandlerMaker(containerInstanceArn *string, cfg *config.Config) func(http.ResponseWriter, *http.Request) {
	resp := &MetadataResponse{
		ClusterArn:           cfg.ClusterArn,
		ContainerInstanceArn: containerInstanceArn,
	}
	responseJSON, _ := json.Marshal(resp)

	return func(w http.ResponseWriter, r *http.Request) {
		w.Write(responseJSON)
	}
}

func NewTaskResponse(task *api.Task, containerMap map[string]*api.DockerContainer) *TaskResponse {
	containers := make([]ContainerResponse, len(containerMap))
	ndx := 0
	for containerName, container := range containerMap {
		containers[ndx] = ContainerResponse{container.DockerId, container.DockerName, containerName}
		ndx++
	}

	return &TaskResponse{
		Arn:           task.Arn,
		DesiredStatus: task.DesiredStatus.String(),
		KnownStatus:   task.KnownStatus.String(),
		Family:        task.Family,
		Version:       task.Version,
		Containers:    containers,
	}
}

func NewTasksResponse(state *dockerstate.DockerTaskEngineState) *TasksResponse {
	allTasks := state.AllTasks()
	taskResponses := make([]*TaskResponse, len(allTasks))
	for ndx, task := range allTasks {
		containerMap, _ := state.ContainerMapByArn(task.Arn)
		taskResponses[ndx] = NewTaskResponse(task, containerMap)
	}

	return &TasksResponse{Tasks: taskResponses}
}

func TasksV1RequestHandlerMaker(taskEngine engine.TaskEngine) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var tasksResponse *TasksResponse
		dockerTaskEngine, ok := taskEngine.(*engine.DockerTaskEngine)
		if ok != true {
			log.Warn("Unable to get DockerTaskEngine from TaskEngine")
			tasksResponse = &TasksResponse{}
		} else {
			tasksResponse = NewTasksResponse(dockerTaskEngine.State())
		}
		responseJSON, _ := json.Marshal(tasksResponse)
		w.Write(responseJSON)
	}
}

func ServeHttp(containerInstanceArn *string, taskEngine engine.TaskEngine, cfg *config.Config) {
	serverFunctions := map[string]func(w http.ResponseWriter, r *http.Request){
		"/v1/metadata": MetadataV1RequestHandlerMaker(containerInstanceArn, cfg),
		"/v1/tasks":    TasksV1RequestHandlerMaker(taskEngine),
	}

	paths := make([]string, 0, len(serverFunctions))
	for path := range serverFunctions {
		paths = append(paths, path)
	}
	availableCommands := &RootResponse{paths}
	// Autogenerated list of the above serverFunctions paths
	availableCommandResponse, _ := json.Marshal(&availableCommands)

	defaultHandler := func(w http.ResponseWriter, r *http.Request) {
		w.Write(availableCommandResponse)
	}

	serverMux := http.NewServeMux()
	serverMux.HandleFunc("/", defaultHandler)
	for key, fn := range serverFunctions {
		serverMux.HandleFunc(key, fn)
	}

	// Log all requests and then pass through to serverMux
	loggingServeMux := http.NewServeMux()
	loggingServeMux.Handle("/", LoggingHandler{serverMux})

	server := http.Server{
		Addr:         ":" + strconv.Itoa(config.AGENT_INTROSPECTION_PORT),
		Handler:      loggingServeMux,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	for {
		err := server.ListenAndServe()
		log.Error("Error running http api", "err", err)
	}
}
<commit_msg>Add error code to response for /tasks api.<commit_after>// Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
//	http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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.

//Handlers for V1

package handlers

import (
	"encoding/json"
	"github.com/aws/amazon-ecs-agent/agent/api"
	"github.com/aws/amazon-ecs-agent/agent/config"
	"github.com/aws/amazon-ecs-agent/agent/engine"
	"github.com/aws/amazon-ecs-agent/agent/engine/dockerstate"
	"github.com/aws/amazon-ecs-agent/agent/logger"
	"net/http"
	"strconv"
	"time"
)

var log = logger.ForModule("Handlers")

const statusBadRequest = 400
const statusNotImplemented = 501
const statusOK = 200
const statusInternalServerError = 500

type RootResponse struct {
	AvailableCommands []string
}

func MetadataV1RequestHandlerMaker(containerInstanceArn *string, cfg *config.Config) func(http.ResponseWriter, *http.Request) {
	resp := &MetadataResponse{
		ClusterArn:           cfg.ClusterArn,
		ContainerInstanceArn: containerInstanceArn,
	}
	responseJSON, _ := json.Marshal(resp)

	return func(w http.ResponseWriter, r *http.Request) {
		w.Write(responseJSON)
	}
}

func NewTaskResponse(task *api.Task, containerMap map[string]*api.DockerContainer) *TaskResponse {
	containers := make([]ContainerResponse, len(containerMap))
	ndx := 0
	for containerName, container := range containerMap {
		containers[ndx] = ContainerResponse{container.DockerId, container.DockerName, containerName}
		ndx++
	}

	return &TaskResponse{
		Arn:           task.Arn,
		DesiredStatus: task.DesiredStatus.String(),
		KnownStatus:   task.KnownStatus.String(),
		Family:        task.Family,
		Version:       task.Version,
		Containers:    containers,
	}
}

func NewTasksResponse(state *dockerstate.DockerTaskEngineState) *TasksResponse {
	allTasks := state.AllTasks()
	taskResponses := make([]*TaskResponse, len(allTasks))
	for ndx, task := range allTasks {
		containerMap, _ := state.ContainerMapByArn(task.Arn)
		taskResponses[ndx] = NewTaskResponse(task, containerMap)
	}

	return &TasksResponse{Tasks: taskResponses}
}

func TasksV1RequestHandlerMaker(taskEngine engine.TaskEngine) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var tasksResponse *TasksResponse
		dockerTaskEngine, ok := taskEngine.(*engine.DockerTaskEngine)
		if ok {
			tasksResponse = NewTasksResponse(dockerTaskEngine.State())
		} else {
			log.Warn("Unable to get DockerTaskEngine from TaskEngine")
			w.WriteHeader(statusInternalServerError)
			tasksResponse = &TasksResponse{}
		}
		responseJSON, _ := json.Marshal(tasksResponse)
		w.Write(responseJSON)
	}
}

func ServeHttp(containerInstanceArn *string, taskEngine engine.TaskEngine, cfg *config.Config) {
	serverFunctions := map[string]func(w http.ResponseWriter, r *http.Request){
		"/v1/metadata": MetadataV1RequestHandlerMaker(containerInstanceArn, cfg),
		"/v1/tasks":    TasksV1RequestHandlerMaker(taskEngine),
	}

	paths := make([]string, 0, len(serverFunctions))
	for path := range serverFunctions {
		paths = append(paths, path)
	}
	availableCommands := &RootResponse{paths}
	// Autogenerated list of the above serverFunctions paths
	availableCommandResponse, _ := json.Marshal(&availableCommands)

	defaultHandler := func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(statusNotImplemented)
		w.Write(availableCommandResponse)
	}

	serverMux := http.NewServeMux()
	serverMux.HandleFunc("/", defaultHandler)
	for key, fn := range serverFunctions {
		serverMux.HandleFunc(key, fn)
	}

	// Log all requests and then pass through to serverMux
	loggingServeMux := http.NewServeMux()
	loggingServeMux.Handle("/", LoggingHandler{serverMux})

	server := http.Server{
		Addr:         ":" + strconv.Itoa(config.AGENT_INTROSPECTION_PORT),
		Handler:      loggingServeMux,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	for {
		err := server.ListenAndServe()
		log.Error("Error running http api", "err", err)
	}
}

{'fraction_non_alphanumeric': 0.11628443010257002, 'fraction_numerical': 0.007721562752103261, 'mean_word_length': 4.712969058591178, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5498629', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2698, 'n_words': 643}