func (server *Server) serveGroup(writer http.ResponseWriter, request *http.Request) { var ( groupID string groupType int ) if strings.HasPrefix(request.URL.Path, urlLibraryPath+"sourcegroups") { groupID = strings.TrimPrefix(request.URL.Path, urlLibraryPath+"sourcegroups/") groupType = library.LibraryItemSourceGroup } else if strings.HasPrefix(request.URL.Path, urlLibraryPath+"metricgroups") { groupID = strings.TrimPrefix(request.URL.Path, urlLibraryPath+"metricgroups/") groupType = library.LibraryItemMetricGroup } switch request.Method { case "DELETE": if groupID == "" { server.serveResponse(writer, serverResponse{mesgMethodNotAllowed}, http.StatusMethodNotAllowed) return } err := server.Library.DeleteItem(groupID, groupType) if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) return } else if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) return } server.serveResponse(writer, nil, http.StatusOK) case "GET", "HEAD": if groupID == "" { server.serveGroupList(writer, request) return } item, err := server.Library.GetItem(groupID, groupType) if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) return } else if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) return } server.serveResponse(writer, item, http.StatusOK) case "POST", "PUT": var group *library.Group if response, status := server.parseStoreRequest(writer, request, groupID); status != http.StatusOK { server.serveResponse(writer, response, status) return } if request.Method == "POST" && request.FormValue("inherit") != "" { // Get group from library item, err := server.Library.GetItem(request.FormValue("inherit"), groupType) if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) return } else if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) return } group = &library.Group{} utils.Clone(item.(*library.Group), group) group.ID = "" } else { // Create a new group instance group = &library.Group{Item: library.Item{ID: groupID}, Type: groupType} } group.Modified = time.Now() // Parse input JSON for group data body, _ := ioutil.ReadAll(request.Body) if err := json.Unmarshal(body, group); err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgResourceInvalid}, http.StatusBadRequest) return } // Store group data err := server.Library.StoreItem(group, groupType) if response, status := server.parseError(writer, request, err); status != http.StatusOK { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, response, status) return } if request.Method == "POST" { writer.Header().Add("Location", strings.TrimRight(request.URL.Path, "/")+"/"+group.ID) server.serveResponse(writer, nil, http.StatusCreated) } else { server.serveResponse(writer, nil, http.StatusOK) } default: server.serveResponse(writer, serverResponse{mesgMethodNotAllowed}, http.StatusMethodNotAllowed) } }
func execGroupHandle(test *testing.T, urlPrefix string, groupBase *library.Group, expandData, expandBase server.ExpandRequest) { baseURL := fmt.Sprintf("http://%s/api/v1/library/%s/", serverConfig.BindAddr, urlPrefix) // Test GET on groups list listBase := server.ItemListResponse{} listResult := server.ItemListResponse{} response := execTestRequest(test, "GET", baseURL, nil, &listResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } if !reflect.DeepEqual(listBase, listResult) { test.Logf("\nExpected %#v\nbut got %#v", listBase, listResult) test.Fail() } // Test GET on a unknown group item response = execTestRequest(test, "GET", baseURL+"/00000000-0000-0000-0000-000000000000", nil, nil) if response.StatusCode != http.StatusNotFound { test.Logf("\nExpected %d\nbut got %d", http.StatusNotFound, response.StatusCode) test.Fail() } // Test POST into group data, _ := json.Marshal(groupBase) response = execTestRequest(test, "POST", baseURL, strings.NewReader(string(data)), nil) if response.StatusCode != http.StatusCreated { test.Logf("\nExpected %d\nbut got %d", http.StatusCreated, response.StatusCode) test.Fail() } if response.Header.Get("Location") == "" { test.Logf("\nExpected `Location' header") test.Fail() } groupBase.ID = response.Header.Get("Location")[strings.LastIndex(response.Header.Get("Location"), "/")+1:] // Test GET on group item groupResult := &library.Group{} response = execTestRequest(test, "GET", baseURL+groupBase.ID, nil, &groupResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } if !reflect.DeepEqual(groupBase, groupResult) { test.Logf("\nExpected %#v\nbut got %#v", groupBase, groupResult) test.Fail() } // Test GET on groups list listBase = server.ItemListResponse{&server.ItemResponse{ ID: groupBase.ID, Name: groupBase.Name, Description: groupBase.Description, }} listResult = server.ItemListResponse{} response = execTestRequest(test, "GET", baseURL, nil, &listResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } for _, listItem := range listResult { listItem.Modified = "" } if !reflect.DeepEqual(listBase, listResult) { test.Logf("\nExpected %#v\nbut got %#v", listBase, listResult) test.Fail() } // Test PUT on group item groupBase.Name = "group0-updated" data, _ = json.Marshal(groupBase) response = execTestRequest(test, "PUT", baseURL+groupBase.ID, strings.NewReader(string(data)), nil) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } // Test GET on group item groupResult = &library.Group{} response = execTestRequest(test, "GET", baseURL+groupBase.ID, nil, &groupResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } if !reflect.DeepEqual(groupBase, groupResult) { test.Logf("\nExpected %#v\nbut got %#v", groupBase, groupResult) test.Fail() } // Test group expansion data, _ = json.Marshal(expandData) expandResult := make([]server.ExpandRequest, 0) response = execTestRequest(test, "POST", fmt.Sprintf("http://%s/api/v1/library/expand", serverConfig.BindAddr), strings.NewReader(string(data)), &expandResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } if len(expandResult) == 0 { test.Logf("\nExpected %#v\nbut got %#v", expandBase, expandResult) test.Fail() } else if !reflect.DeepEqual(expandBase, expandResult[0]) { test.Logf("\nExpected %#v\nbut got %#v", expandBase, expandResult[0]) test.Fail() } // Test DELETE on group item response = execTestRequest(test, "DELETE", baseURL+groupBase.ID, nil, nil) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } response = execTestRequest(test, "DELETE", baseURL+groupBase.ID, nil, nil) if response.StatusCode != http.StatusNotFound { test.Logf("\nExpected %d\nbut got %d", http.StatusNotFound, response.StatusCode) test.Fail() } // Test GET on groups list (offset and limit) listBase = server.ItemListResponse{} for i := 0; i < 3; i += 1 { groupTemp := &library.Group{} utils.Clone(groupBase, groupTemp) groupTemp.ID = "" groupTemp.Name = fmt.Sprintf("group0-%d", i) data, _ = json.Marshal(groupTemp) response = execTestRequest(test, "POST", baseURL, strings.NewReader(string(data)), nil) if response.StatusCode != http.StatusCreated { test.Logf("\nExpected %d\nbut got %d", http.StatusCreated, response.StatusCode) test.Fail() } location := response.Header.Get("Location") if location == "" { test.Logf("\nExpected `Location' header") test.Fail() } groupTemp.ID = location[strings.LastIndex(location, "/")+1:] listBase = append(listBase, &server.ItemResponse{ ID: groupTemp.ID, Name: groupTemp.Name, Description: groupTemp.Description, }) } listResult = server.ItemListResponse{} response = execTestRequest(test, "GET", baseURL, nil, &listResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } for _, listItem := range listResult { listItem.Modified = "" } if !reflect.DeepEqual(listBase, listResult) { test.Logf("\nExpected %#v\nbut got %#v", listBase, listResult) test.Fail() } listResult = server.ItemListResponse{} response = execTestRequest(test, "GET", baseURL+"?limit=1", nil, &listResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } for _, listItem := range listResult { listItem.Modified = "" } if !reflect.DeepEqual(listBase[:1], listResult) { test.Logf("\nExpected %#v\nbut got %#v", listBase[:1], listResult) test.Fail() } listResult = server.ItemListResponse{} response = execTestRequest(test, "GET", baseURL+"?offset=1&limit=2", nil, &listResult) if response.StatusCode != http.StatusOK { test.Logf("\nExpected %d\nbut got %d", http.StatusOK, response.StatusCode) test.Fail() } for _, listItem := range listResult { listItem.Modified = "" } if !reflect.DeepEqual(listBase[1:3], listResult) { test.Logf("\nExpected %#v\nbut got %#v", listBase[1:3], listResult) test.Fail() } }