This is an automated email from the ASF dual-hosted git repository.
zrhoffman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 257af6a Added the ability to change a server capability name (#5605)
257af6a is described below
commit 257af6ad3dce237f7f113c0a6ef460248f5a8917
Author: Rima Shah <[email protected]>
AuthorDate: Wed Mar 10 16:03:44 2021 -0700
Added the ability to change a server capability name (#5605)
* Added new PUT route to update name for server capabilities
* Updated TP to make name field on server capabilities page mutable
Added DB migration script for cascading PK to other associated tables.
* Updated TP end-to-end test case.
* Updated documentation
* Added TO API-v4 test case for update server capability
* Updated changelo
* Updated TO-API test case.
* Updated TO API/v4 test-1
* Resolved server capability url for servers and DS.
* removed extra break line and added to check no two users can modify the
name at the same time.
* Added checks to avoid panic
* Updated test case and added check for LastUpdatedTime
* Removed commented line.
* Updated error message.
* Addressed review comment.
* Updated server server capability test case.
---
CHANGELOG.md | 1 +
docs/source/api/v4/server_capabilities.rst | 60 ++++++++++++++++++++
...0300000000_server_capability_update_cascade.sql | 25 +++++++++
.../testing/api/v4/servercapabilities_test.go | 42 ++++++++++++++
.../testing/api/v4/serverservercapability_test.go | 64 ++++++++++++++++++++++
traffic_ops/traffic_ops_golang/routing/routes.go | 1 +
.../servercapability/servercapability.go | 55 +++++++++++++++++++
traffic_ops/v4-client/servercapability.go | 11 ++++
traffic_portal/app/src/app.js | 4 +-
.../app/src/common/api/ServerCapabilityService.js | 16 +++++-
.../FormServerCapabilityController.js | 4 +-
.../FormEditServerCapabilityController.js} | 17 ++++--
.../form/serverCapability/{view => edit}/index.js | 2 +-
.../form.serverCapability.tpl.html | 5 +-
.../new/FormNewServerCapabilityController.js | 5 +-
.../TableServerCapabilitiesController.js | 24 ++++----
.../table.serverCapabilities.tpl.html | 2 +-
.../serverCapabilities/deliveryServices/index.js | 6 +-
.../serverCapabilities/{view => edit}/index.js | 8 +--
.../private/serverCapabilities/servers/index.js | 6 +-
.../test/end_to_end/serverCapabilities/pageData.js | 1 +
.../serverCapabilities/server-capabilities-spec.js | 8 ++-
22 files changed, 327 insertions(+), 40 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 703e8dd..7eb8d47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).
## [unreleased]
### Added
+- Traffic Ops/Traffic Portal:
[#5479](https://github.com/apache/trafficcontrol/issues/5479) - Added the
ability to change a server capability name
- Traffic Ops: [#3577](https://github.com/apache/trafficcontrol/issues/3577) -
Added a query param (server host_name or ID) for servercheck API
- Traffic Portal:
[#5318](https://github.com/apache/trafficcontrol/issues/5318) - Rename server
columns for IPv4 address fields.
- Traffic Portal:
[#5361](https://github.com/apache/trafficcontrol/issues/5361) - Added the
ability to change the name of a topology.
diff --git a/docs/source/api/v4/server_capabilities.rst
b/docs/source/api/v4/server_capabilities.rst
index fa605cf..3a732ae 100644
--- a/docs/source/api/v4/server_capabilities.rst
+++ b/docs/source/api/v4/server_capabilities.rst
@@ -135,6 +135,66 @@ Response Structure
}
}
+``PUT``
+========
+Update an existing :term:`Server Capability`.
+
+:Auth. Required: Yes
+:Roles Required: "admin" or "operations"
+:Response Type: Object
+
+Request Structure
+-----------------
+:name: The name of the :term:`Server Capability`
+
+.. code-block:: http
+ :caption: Request Example
+
+ PUT /api/4.0/server_capabilities/edit?name=RAM HTTP/1.1
+ Host: trafficops.infra.ciab.test
+ User-Agent: curl/7.47.0
+ Accept: */*
+ Cookie: mojolicious=...
+ Content-Length: 15
+ Content-Type: application/json
+
+ {
+ "name": "HDD"
+ }
+
+Response Structure
+------------------
+:name: The name of this :term:`Server Capability`
+:lastUpdated: The date and time at which this :term:`Server Capability` was
last updated, in ISO-like format
+
+.. code-block:: http
+ :caption: Response Example
+
+ HTTP/1.1 200 OK
+ Access-Control-Allow-Credentials: true
+ Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type,
Accept, Set-Cookie, Cookie
+ Access-Control-Allow-Methods: POST,GET,OPTIONS,PUT,DELETE
+ Access-Control-Allow-Origin: *
+ Content-Type: application/json
+ Set-Cookie: mojolicious=...; Path=/; Expires=Mon, 18 Nov 2019 17:40:54
GMT; Max-Age=3600; HttpOnly
+ Whole-Content-Sha512:
ysdopC//JQI79BRUa61s6M2HzHxYHpo5RdcuauOoqCYxiVOoUhNZfOVydVkv8zDN2qA374XKnym4kWj3VzQIXg==
+ X-Server-Name: traffic_ops_golang/
+ Date: Wed, 03 March 2021 21:22:08 GMT
+ Content-Length: 137
+
+ {
+ "alerts": [
+ {
+ "text": "server capability was updated.",
+ "level": "success"
+ }
+ ],
+ "response": {
+ "name": "HDD",
+ "lastUpdated": "2021-03-03 21:22:08+00"
+ }
+ }
+
``DELETE``
==========
Deletes a specific :term:`Server Capability`.
diff --git
a/traffic_ops/app/db/migrations/2021030300000000_server_capability_update_cascade.sql
b/traffic_ops/app/db/migrations/2021030300000000_server_capability_update_cascade.sql
new file mode 100644
index 0000000..d2e0b55
--- /dev/null
+++
b/traffic_ops/app/db/migrations/2021030300000000_server_capability_update_cascade.sql
@@ -0,0 +1,25 @@
+/*
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License 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.
+*/
+
+-- +goose Up
+-- SQL in section 'Up' is executed when this migration is applied
+ALTER TABLE public.server_server_capability DROP CONSTRAINT
fk_server_capability;
+ALTER TABLE public.deliveryservices_required_capability DROP CONSTRAINT
fk_required_capability;
+ALTER TABLE public.server_server_capability ADD CONSTRAINT
fk_server_capability FOREIGN KEY (server_capability) REFERENCES
server_capability(name) ON UPDATE CASCADE ON DELETE RESTRICT;
+ALTER TABLE public.deliveryservices_required_capability ADD CONSTRAINT
fk_required_capability FOREIGN KEY (required_capability) REFERENCES
server_capability(name) ON UPDATE CASCADE ON DELETE RESTRICT;
+
+-- +goose Down
+-- SQL section 'Down' is executed when this migration is rolled back
+ALTER TABLE public.server_server_capability DROP CONSTRAINT
fk_server_capability;
+ALTER TABLE public.deliveryservices_required_capability DROP CONSTRAINT
fk_required_capability;
+ALTER TABLE public.server_server_capability ADD CONSTRAINT
fk_server_capability FOREIGN KEY (server_capability) REFERENCES
server_capability(name) ON DELETE RESTRICT;
+ALTER TABLE public.deliveryservices_required_capability ADD CONSTRAINT
fk_required_capability FOREIGN KEY (required_capability) REFERENCES
server_capability(name) ON DELETE RESTRICT;
diff --git a/traffic_ops/testing/api/v4/servercapabilities_test.go
b/traffic_ops/testing/api/v4/servercapabilities_test.go
index a0bcdeb..6ad6b1d 100644
--- a/traffic_ops/testing/api/v4/servercapabilities_test.go
+++ b/traffic_ops/testing/api/v4/servercapabilities_test.go
@@ -28,6 +28,7 @@ func TestServerCapabilities(t *testing.T) {
SortTestServerCapabilities(t)
GetTestServerCapabilities(t)
ValidationTestServerCapabilities(t)
+ UpdateTestServerCapabilities(t)
})
}
@@ -89,6 +90,47 @@ func ValidationTestServerCapabilities(t *testing.T) {
}
}
+func UpdateTestServerCapabilities(t *testing.T) {
+ var header http.Header
+
+ // Get server capability name and edit it to a new name
+ resp, _, err := TOSession.GetServerCapabilitiesWithHdr(header)
+ if err != nil {
+ t.Fatalf("Expected no error, but got %v", err.Error())
+ }
+ if len(resp) == 0 {
+ t.Fatalf("no server capability in response, quitting")
+ }
+ origName := resp[0].Name
+ newSCName := "sc-test"
+ resp[0].Name = newSCName
+
+ // Update server capability with new name
+ updateResponse, _, err :=
TOSession.UpdateServerCapabilityByName(origName, &resp[0])
+ if err != nil {
+ t.Errorf("cannot PUT server capability: %v - %v", err,
updateResponse)
+ }
+
+ // Get updated name
+ getResp, _, err := TOSession.GetServerCapabilityWithHdr(newSCName,
header)
+ if err != nil {
+ t.Fatalf("Expected no error, but %v", err.Error())
+ }
+ if getResp == nil {
+ t.Fatalf("no server capability in response, quitting")
+ }
+ if getResp.Name != newSCName {
+ t.Errorf("failed to update server capability name, expected: %v
but got: %v", newSCName, updateResponse.Name)
+ }
+
+ // Set everything back as it was for further testing.
+ resp[0].Name = origName
+ r, _, err := TOSession.UpdateServerCapabilityByName(newSCName, &resp[0])
+ if err != nil {
+ t.Errorf("cannot PUT seerver capability: %v - %v", err, r)
+ }
+}
+
func DeleteTestServerCapabilities(t *testing.T) {
for _, sc := range testData.ServerCapabilities {
diff --git a/traffic_ops/testing/api/v4/serverservercapability_test.go
b/traffic_ops/testing/api/v4/serverservercapability_test.go
index 3cc7475..b8e7d25 100644
--- a/traffic_ops/testing/api/v4/serverservercapability_test.go
+++ b/traffic_ops/testing/api/v4/serverservercapability_test.go
@@ -34,6 +34,7 @@ func TestServerServerCapabilities(t *testing.T) {
GetTestServerServerCapabilitiesIMS(t)
GetTestServerServerCapabilities(t)
GetDeliveryServiceServersWithCapabilities(t)
+ UpdateTestServerServerCapabilities(t)
})
}
@@ -222,6 +223,69 @@ func GetTestServerServerCapabilities(t *testing.T) {
}
}
+func UpdateTestServerServerCapabilities(t *testing.T) {
+ var header http.Header
+
+ // Get server capability name and edit it to a new name
+ resp, _, err := TOSession.GetServerCapabilitiesWithHdr(header)
+ if err != nil {
+ t.Fatalf("Expected no error, but got %v", err.Error())
+ }
+ if len(resp) == 0 {
+ t.Fatal("no server capability in response, quitting")
+ }
+ origName := resp[0].Name
+ newSCName := "sc-test"
+ resp[0].Name = newSCName
+
+ // Get all servers related to original sever capability name
+ servOrigResp, _, err :=
TOSession.GetServerServerCapabilitiesWithHdr(nil, nil, &origName, nil)
+ if err != nil {
+ t.Fatalf("cannot GET server capabilities assigned to servers by
server capability name %v: %v", origName, err)
+ }
+ if len(servOrigResp) == 0 {
+ t.Fatalf("no servers associated with server capability name:
%v", origName)
+ }
+ mapOrigServ := make(map[string]string)
+ for _, s := range servOrigResp {
+ mapOrigServ[*s.Server] = *s.ServerCapability
+ }
+
+ // Update server capability with new name
+ updateResponse, _, err :=
TOSession.UpdateServerCapabilityByName(origName, &resp[0])
+ if err != nil {
+ t.Errorf("cannot PUT server capability: %v - %v", err,
updateResponse)
+ }
+
+ //To check whether the primary key change trickled down to server table
+ servUpdatedResp, _, err :=
TOSession.GetServerServerCapabilitiesWithHdr(nil, nil, &newSCName, nil)
+ if err != nil {
+ t.Fatalf("cannot GET server capabilities assigned to servers by
server capability name %v: %v", newSCName, err)
+ }
+ if len(servUpdatedResp) == 0 {
+ t.Fatalf("no server associated with server capability name:%v",
newSCName)
+ }
+ if len(servOrigResp) != len(servUpdatedResp) {
+ t.Fatalf("length of servers for a given server capability name
is different, expected: %v-%v, got: %v-%v", origName, len(servOrigResp),
newSCName, len(servUpdatedResp))
+ }
+ for _, s := range servUpdatedResp {
+ if newSCName != *s.ServerCapability {
+ t.Errorf("GET server server capabilities by server
capability returned non-matching server capability: %v", *s.ServerCapability)
+ }
+ _, ok := mapOrigServ[*s.Server]
+ if !ok {
+ t.Fatalf("server capability name change didn't trickle
to server: %v", *s.Server)
+ }
+ }
+
+ // Set everything back as it was for further testing.
+ resp[0].Name = origName
+ r, _, err := TOSession.UpdateServerCapabilityByName(newSCName, &resp[0])
+ if err != nil {
+ t.Errorf("cannot PUT seerver capability: %v - %v", err, r)
+ }
+}
+
func DeleteTestServerServerCapabilities(t *testing.T) {
// Get Server Capabilities to delete them
sscs, _, err := TOSession.GetServerServerCapabilitiesWithHdr(nil, nil,
nil, nil)
diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go
b/traffic_ops/traffic_ops_golang/routing/routes.go
index f7794b7..d416637 100644
--- a/traffic_ops/traffic_ops_golang/routing/routes.go
+++ b/traffic_ops/traffic_ops_golang/routing/routes.go
@@ -326,6 +326,7 @@ func Routes(d ServerData) ([]Route, []RawRoute,
http.Handler, error) {
//Server Capability
{api.Version{4, 0}, http.MethodGet, `server_capabilities$`,
api.ReadHandler(&servercapability.TOServerCapability{}),
auth.PrivLevelReadOnly, Authenticated, nil, 4104073913},
{api.Version{4, 0}, http.MethodPost, `server_capabilities$`,
api.CreateHandler(&servercapability.TOServerCapability{}),
auth.PrivLevelOperations, Authenticated, nil, 40744707083},
+ {api.Version{4, 0}, http.MethodPut, `server_capabilities$`,
api.UpdateHandler(&servercapability.TOServerCapability{}),
auth.PrivLevelOperations, Authenticated, nil, 42543770109},
{api.Version{4, 0}, http.MethodDelete, `server_capabilities$`,
api.DeleteHandler(&servercapability.TOServerCapability{}),
auth.PrivLevelOperations, Authenticated, nil, 4364150383},
//Server Server Capabilities: CRUD
diff --git
a/traffic_ops/traffic_ops_golang/servercapability/servercapability.go
b/traffic_ops/traffic_ops_golang/servercapability/servercapability.go
index b16235c..fc9d843 100644
--- a/traffic_ops/traffic_ops_golang/servercapability/servercapability.go
+++ b/traffic_ops/traffic_ops_golang/servercapability/servercapability.go
@@ -20,6 +20,11 @@ package servercapability
*/
import (
+ "database/sql"
+ "errors"
+ "fmt"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/lib/go-util"
@@ -33,6 +38,7 @@ import (
type TOServerCapability struct {
api.APIInfoImpl `json:"-"`
+ RequestedName string
tc.ServerCapability
}
@@ -60,6 +66,15 @@ FROM
`
}
+func (v *TOServerCapability) updateQuery() string {
+ return `
+UPDATE server_capability sc SET
+ name = $1
+WHERE sc.name = $2
+RETURNING sc.name, sc.last_updated
+`
+}
+
func (v *TOServerCapability) DeleteQuery() string {
return `
DELETE FROM server_capability WHERE name=:name
@@ -82,6 +97,7 @@ func (v TOServerCapability) GetKeys()
(map[string]interface{}, bool) {
}
func (v *TOServerCapability) SetKeys(keys map[string]interface{}) {
+ v.RequestedName = v.Name
v.Name, _ = keys["name"].(string)
}
@@ -105,6 +121,45 @@ func (v *TOServerCapability) Read(h http.Header, useIMS
bool) ([]interface{}, er
api.DefaultSort(v.APIInfo(), "name")
return api.GenericRead(h, v, useIMS)
}
+
+func (v *TOServerCapability) Update(h http.Header) (error, error, int) {
+ sc, userErr, sysErr, errCode, _ := v.Read(h, false)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, errCode
+ }
+ if len(sc) != 1 {
+ return fmt.Errorf("cannot find exactly one server capability
with the query string provided"), nil, http.StatusBadRequest
+ }
+
+ // check if the name was being updated by someone else
+ var existingLastUpdated *tc.TimeNoMod
+ q := `SELECT last_updated FROM server_capability WHERE name = $1`
+ if err := v.ReqInfo.Tx.QueryRow(q, v.Name).Scan(&existingLastUpdated);
err != nil {
+ if err == sql.ErrNoRows {
+ return errors.New("server capability was not found"),
nil, http.StatusNotFound
+ }
+ return nil, errors.New("server capability update: querying: " +
err.Error()), http.StatusInternalServerError
+ }
+ if !api.IsUnmodified(h, existingLastUpdated.Time) {
+ return errors.New("the resource has been modified since the
time specified by the request headers"), nil, http.StatusPreconditionFailed
+ }
+
+ // udpate server capability name
+ rows, err := v.ReqInfo.Tx.Query(v.updateQuery(), v.RequestedName,
v.Name)
+ if err != nil {
+ return nil, fmt.Errorf("server capability update: error setting
the name for server capability %v: %v", v.Name, err.Error()),
http.StatusInternalServerError
+ }
+ defer log.Close(rows, "unable to close DB connection")
+
+ for rows.Next() {
+ err = rows.Scan(&v.Name, &v.LastUpdated)
+ if err != nil {
+ return api.ParseDBError(err)
+ }
+ }
+ return nil, nil, http.StatusOK
+}
+
func (v *TOServerCapability) SelectMaxLastUpdatedQuery(where, orderBy,
pagination, tableName string) string {
return `SELECT max(t) from (
SELECT max(sc.last_updated) as t from server_capability sc ` +
where + orderBy + pagination +
diff --git a/traffic_ops/v4-client/servercapability.go
b/traffic_ops/v4-client/servercapability.go
index 49864cb..aaf5dab 100644
--- a/traffic_ops/v4-client/servercapability.go
+++ b/traffic_ops/v4-client/servercapability.go
@@ -69,6 +69,17 @@ func (to *Session) GetServerCapability(name string)
(*tc.ServerCapability, tocli
return to.GetServerCapabilityWithHdr(name, nil)
}
+// UpdateServerCapabilityByName updates a Server Capability by name.
+func (to *Session) UpdateServerCapabilityByName(name string, sc
*tc.ServerCapability) (*tc.ServerCapability, toclientlib.ReqInf, error) {
+ route := fmt.Sprintf("%s?name=%s", APIServerCapabilities,
url.QueryEscape(name))
+ var data tc.ServerCapability
+ reqInf, err := to.put(route, sc, nil, &data)
+ if err != nil {
+ return nil, reqInf, err
+ }
+ return &data, reqInf, nil
+}
+
// DeleteServerCapability deletes the given server capability by name.
func (to *Session) DeleteServerCapability(name string) (tc.Alerts,
toclientlib.ReqInf, error) {
reqUrl := fmt.Sprintf("%s?name=%s", APIServerCapabilities,
url.QueryEscape(name))
diff --git a/traffic_portal/app/src/app.js b/traffic_portal/app/src/app.js
index fb57a75..0e47f22 100644
--- a/traffic_portal/app/src/app.js
+++ b/traffic_portal/app/src/app.js
@@ -186,7 +186,7 @@ var trafficPortal = angular.module('trafficPortal', [
require('./modules/private/serverCapabilities/list').name,
require('./modules/private/serverCapabilities/new').name,
require('./modules/private/serverCapabilities/servers').name,
- require('./modules/private/serverCapabilities/view').name,
+ require('./modules/private/serverCapabilities/edit').name,
require('./modules/private/servers').name,
require('./modules/private/servers/capabilities').name,
require('./modules/private/servers/deliveryServices').name,
@@ -325,7 +325,7 @@ var trafficPortal = angular.module('trafficPortal', [
require('./common/modules/form/role/new').name,
require('./common/modules/form/serverCapability').name,
require('./common/modules/form/serverCapability/new').name,
- require('./common/modules/form/serverCapability/view').name,
+ require('./common/modules/form/serverCapability/edit').name,
require('./common/modules/form/server').name,
require('./common/modules/form/server/edit').name,
require('./common/modules/form/server/new').name,
diff --git a/traffic_portal/app/src/common/api/ServerCapabilityService.js
b/traffic_portal/app/src/common/api/ServerCapabilityService.js
index dfdcad9..2f1793f 100644
--- a/traffic_portal/app/src/common/api/ServerCapabilityService.js
+++ b/traffic_portal/app/src/common/api/ServerCapabilityService.js
@@ -68,6 +68,18 @@ var ServerCapabilityService = function($http, ENV,
locationUtils, messageModel)
);
};
+ this.updateServerCapability = function(currentName, serverCapability) {
+ return $http.put(ENV.api['root'] + 'server_capabilities',
serverCapability, {params: {"name": currentName}}).then(
+ function(result) {
+ return result;
+ },
+ function(err) {
+ messageModel.setMessages(err.data.alerts,
false);
+ throw err;
+ }
+ );
+ };
+
this.getServerCapabilityServers = function(capabilityName) {
return $http.get(ENV.api['root'] +
'server_server_capabilities', { params: { serverCapability: capabilityName }
}).then(
function (result) {
@@ -76,7 +88,7 @@ var ServerCapabilityService = function($http, ENV,
locationUtils, messageModel)
function (err) {
throw err;
}
- )
+ );
};
this.getServerCapabilityDeliveryServices = function(capabilityName) {
@@ -87,7 +99,7 @@ var ServerCapabilityService = function($http, ENV,
locationUtils, messageModel)
function (err) {
throw err;
}
- )
+ );
};
};
diff --git
a/traffic_portal/app/src/common/modules/form/serverCapability/FormServerCapabilityController.js
b/traffic_portal/app/src/common/modules/form/serverCapability/FormServerCapabilityController.js
index 9810512..efc2bdc 100644
---
a/traffic_portal/app/src/common/modules/form/serverCapability/FormServerCapabilityController.js
+++
b/traffic_portal/app/src/common/modules/form/serverCapability/FormServerCapabilityController.js
@@ -22,11 +22,11 @@ var FormServerCapabilityController =
function(serverCapability, $scope, $locatio
$scope.serverCapability = serverCapability;
$scope.viewServers = function() {
- $location.path($location.path() + '/servers');
+ $location.path('/server-capabilities/servers');
};
$scope.viewDeliveryServices = function() {
- $location.path($location.path() + '/delivery-services');
+ $location.path('/server-capabilities/delivery-services');
};
$scope.navigateToPath = locationUtils.navigateToPath;
diff --git
a/traffic_portal/app/src/common/modules/form/serverCapability/view/FormViewServerCapabilityController.js
b/traffic_portal/app/src/common/modules/form/serverCapability/edit/FormEditServerCapabilityController.js
similarity index 74%
rename from
traffic_portal/app/src/common/modules/form/serverCapability/view/FormViewServerCapabilityController.js
rename to
traffic_portal/app/src/common/modules/form/serverCapability/edit/FormEditServerCapabilityController.js
index 8a8eaf8..275e3bd 100644
---
a/traffic_portal/app/src/common/modules/form/serverCapability/view/FormViewServerCapabilityController.js
+++
b/traffic_portal/app/src/common/modules/form/serverCapability/edit/FormEditServerCapabilityController.js
@@ -17,7 +17,7 @@
* under the License.
*/
-var FormViewServerCapabilityController = function(serverCapability, $scope,
$controller, $uibModal, $anchorScroll, locationUtils, serverCapabilityService) {
+var FormEditServerCapabilityController = function(serverCapability, $scope,
$controller, $uibModal, $anchorScroll, locationUtils, messageModel,
serverCapabilityService) {
// extends the FormServerCapabilityController to inherit common methods
angular.extend(this, $controller('FormServerCapabilityController', {
serverCapability: serverCapability, $scope: $scope }));
@@ -32,7 +32,8 @@ var FormViewServerCapabilityController =
function(serverCapability, $scope, $con
$scope.serverCapabilityName = serverCapability.name;
$scope.settings = {
- isNew: false
+ isNew: false,
+ saveLabel: 'Update'
};
$scope.confirmDelete = function(serverCapability) {
@@ -55,7 +56,15 @@ var FormViewServerCapabilityController =
function(serverCapability, $scope, $con
});
};
+ $scope.save = function(currentName, serverCapability) {
+ serverCapabilityService.updateServerCapability(currentName,
serverCapability).
+ then(function(result) {
+ messageModel.setMessages(result.data.alerts,
currentName !== serverCapability.name);
+
locationUtils.navigateToPath('/server-capabilities/edit?name=' +
result.data.response.name);
+ });
+ };
+
};
-FormViewServerCapabilityController.$inject = ['serverCapability', '$scope',
'$controller', '$uibModal', '$anchorScroll', 'locationUtils',
'serverCapabilityService'];
-module.exports = FormViewServerCapabilityController;
+FormEditServerCapabilityController.$inject = ['serverCapability', '$scope',
'$controller', '$uibModal', '$anchorScroll', 'locationUtils', 'messageModel',
'serverCapabilityService'];
+module.exports = FormEditServerCapabilityController;
diff --git
a/traffic_portal/app/src/common/modules/form/serverCapability/view/index.js
b/traffic_portal/app/src/common/modules/form/serverCapability/edit/index.js
similarity index 89%
rename from
traffic_portal/app/src/common/modules/form/serverCapability/view/index.js
rename to
traffic_portal/app/src/common/modules/form/serverCapability/edit/index.js
index 06edc8f..cce2495 100644
--- a/traffic_portal/app/src/common/modules/form/serverCapability/view/index.js
+++ b/traffic_portal/app/src/common/modules/form/serverCapability/edit/index.js
@@ -18,4 +18,4 @@
*/
module.exports = angular.module('trafficPortal.form.serverCapability.view', [])
- .controller('FormViewServerCapabilityController',
require('./FormViewServerCapabilityController'));
+ .controller('FormEditServerCapabilityController',
require('./FormEditServerCapabilityController'));
diff --git
a/traffic_portal/app/src/common/modules/form/serverCapability/form.serverCapability.tpl.html
b/traffic_portal/app/src/common/modules/form/serverCapability/form.serverCapability.tpl.html
index 823a8f2..3bd82b9 100644
---
a/traffic_portal/app/src/common/modules/form/serverCapability/form.serverCapability.tpl.html
+++
b/traffic_portal/app/src/common/modules/form/serverCapability/form.serverCapability.tpl.html
@@ -35,7 +35,7 @@ under the License.
<div class="form-group" ng-class="{'has-error':
hasError(serverCapabilityForm.name), 'has-feedback':
hasError(serverCapabilityForm.name)}">
<label for="name" class="control-label col-md-2 col-sm-2
col-xs-12">Name *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
- <input id="name" name="name" type="text"
class="form-control" ng-disabled="!settings.isNew"
ng-model="serverCapability.name" required pattern="^[a-zA-Z0-9_-]+$" autofocus>
+ <input id="name" name="name" type="text"
class="form-control" ng-model="serverCapability.name" required
pattern="^[a-zA-Z0-9_-]+$" autofocus>
<small class="input-error"
ng-show="hasPropertyError(serverCapabilityForm.name,
'required')">Required</small>
<small class="input-error"
ng-show="hasPropertyError(serverCapabilityForm.name, 'pattern')">Must be
alphamumeric with no spaces. Dashes and underscores also allowed.</small>
<span ng-show="hasError(serverCapabilityForm.name)"
class="form-control-feedback"><i class="fa fa-times"></i></span>
@@ -43,7 +43,8 @@ under the License.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger"
ng-if="!settings.isNew"
ng-click="confirmDelete(serverCapability)">Delete</button>
- <button type="button" class="btn btn-success"
ng-if="settings.isNew" ng-disabled="serverCapabilityForm.$pristine ||
serverCapabilityForm.$invalid" ng-click="save(serverCapability)">Create</button>
+ <button type="button" class="btn btn-success"
ng-if="settings.isNew" ng-disabled="serverCapabilityForm.$pristine ||
serverCapabilityForm.$invalid"
ng-click="save(serverCapability)">{{settings.saveLabel}}</button>
+ <button type="button" class="btn btn-success"
ng-if="!settings.isNew" ng-disabled="serverCapabilityForm.$pristine ||
serverCapabilityForm.$invalid" ng-click="save(serverCapabilityName,
serverCapability)">{{settings.saveLabel}}</button>
</div>
</form>
</div>
diff --git
a/traffic_portal/app/src/common/modules/form/serverCapability/new/FormNewServerCapabilityController.js
b/traffic_portal/app/src/common/modules/form/serverCapability/new/FormNewServerCapabilityController.js
index bea2b03..e017ba9 100644
---
a/traffic_portal/app/src/common/modules/form/serverCapability/new/FormNewServerCapabilityController.js
+++
b/traffic_portal/app/src/common/modules/form/serverCapability/new/FormNewServerCapabilityController.js
@@ -25,11 +25,12 @@ var FormNewServerCapabilityController =
function(serverCapability, $scope, $cont
$scope.serverCapabilityName = 'New';
$scope.settings = {
- isNew: true
+ isNew: true,
+ saveLabel: 'Create'
};
$scope.save = function(serverCapability) {
- serverCapabilityService.createServerCapability(serverCapability)
+
serverCapabilityService.createServerCapability(serverCapability);
};
};
diff --git
a/traffic_portal/app/src/common/modules/table/serverCapabilities/TableServerCapabilitiesController.js
b/traffic_portal/app/src/common/modules/table/serverCapabilities/TableServerCapabilitiesController.js
index d7d7907..997665d 100644
---
a/traffic_portal/app/src/common/modules/table/serverCapabilities/TableServerCapabilitiesController.js
+++
b/traffic_portal/app/src/common/modules/table/serverCapabilities/TableServerCapabilitiesController.js
@@ -19,6 +19,14 @@
var TableServerCapabilitiesController = function(serverCapabilities, $scope,
$state, $uibModal, $window, locationUtils, serverCapabilityService,
messageModel) {
+ var deleteServerCapability = function(serverCapability) {
+
serverCapabilityService.deleteServerCapability(serverCapability.name)
+ .then(function(result) {
+ messageModel.setMessages(result.alerts, false);
+ $scope.refresh();
+ });
+ };
+
var confirmDelete = function(serverCapability) {
var params = {
title: 'Delete Server Capability: ' +
serverCapability.name,
@@ -39,14 +47,6 @@ var TableServerCapabilitiesController =
function(serverCapabilities, $scope, $st
});
};
- var deleteServerCapability = function(serverCapability) {
-
serverCapabilityService.deleteServerCapability(serverCapability.name)
- .then(function(result) {
- messageModel.setMessages(result.alerts, false);
- $scope.refresh();
- });
- };
-
$scope.serverCapabilities = serverCapabilities;
$scope.contextMenuItems = [
@@ -58,9 +58,9 @@ var TableServerCapabilitiesController =
function(serverCapabilities, $scope, $st
},
null, // Dividier
{
- text: 'View',
+ text: 'Edit',
click: function ($itemScope) {
- $scope.viewServerCapability($itemScope.sc.name);
+ $scope.editServerCapability($itemScope.sc.name);
}
},
{
@@ -88,8 +88,8 @@ var TableServerCapabilitiesController =
function(serverCapabilities, $scope, $st
locationUtils.navigateToPath('/server-capabilities/new');
};
- $scope.viewServerCapability = function(name) {
- locationUtils.navigateToPath('/server-capabilities/' + name);
+ $scope.editServerCapability = function(name) {
+ locationUtils.navigateToPath('/server-capabilities/edit?name='
+ name);
};
$scope.refresh = function() {
diff --git
a/traffic_portal/app/src/common/modules/table/serverCapabilities/table.serverCapabilities.tpl.html
b/traffic_portal/app/src/common/modules/table/serverCapabilities/table.serverCapabilities.tpl.html
index 2d94004..130cd30 100644
---
a/traffic_portal/app/src/common/modules/table/serverCapabilities/table.serverCapabilities.tpl.html
+++
b/traffic_portal/app/src/common/modules/table/serverCapabilities/table.serverCapabilities.tpl.html
@@ -37,7 +37,7 @@ under the License.
</tr>
</thead>
<tbody>
- <tr ng-click="viewServerCapability(sc.name)" ng-repeat="sc in
::serverCapabilities" context-menu="contextMenuItems">
+ <tr ng-click="editServerCapability(sc.name)" ng-repeat="sc in
::serverCapabilities" context-menu="contextMenuItems">
<td name="name"
data-search="^{{::sc.name}}$">{{::sc.name}}</td>
</tr>
</tbody>
diff --git
a/traffic_portal/app/src/modules/private/serverCapabilities/deliveryServices/index.js
b/traffic_portal/app/src/modules/private/serverCapabilities/deliveryServices/index.js
index a77f05d..988ca96 100644
---
a/traffic_portal/app/src/modules/private/serverCapabilities/deliveryServices/index.js
+++
b/traffic_portal/app/src/modules/private/serverCapabilities/deliveryServices/index.js
@@ -21,17 +21,17 @@ module.exports =
angular.module('trafficPortal.private.serverCapabilities.delive
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('trafficPortal.private.serverCapabilities.deliveryServices', {
- url: '/{serverCapability}/delivery-services',
+ url: '/delivery-services?name',
views: {
serverCapabilitiesContent: {
templateUrl:
'common/modules/table/serverCapabilityDeliveryServices/table.serverCapabilityDeliveryServices.tpl.html',
controller:
'TableServerCapabilityDeliveryServicesController',
resolve: {
serverCapability:
function($stateParams, serverCapabilityService) {
- return
serverCapabilityService.getServerCapability($stateParams.serverCapability);
+ return
serverCapabilityService.getServerCapability($stateParams.name);
},
deliveryServices:
function($stateParams, serverCapabilityService) {
- return
serverCapabilityService.getServerCapabilityDeliveryServices($stateParams.serverCapability);
+ return
serverCapabilityService.getServerCapabilityDeliveryServices($stateParams.name);
}
}
}
diff --git
a/traffic_portal/app/src/modules/private/serverCapabilities/view/index.js
b/traffic_portal/app/src/modules/private/serverCapabilities/edit/index.js
similarity index 88%
rename from
traffic_portal/app/src/modules/private/serverCapabilities/view/index.js
rename to
traffic_portal/app/src/modules/private/serverCapabilities/edit/index.js
index 2e71427..61e19b0 100644
--- a/traffic_portal/app/src/modules/private/serverCapabilities/view/index.js
+++ b/traffic_portal/app/src/modules/private/serverCapabilities/edit/index.js
@@ -20,15 +20,15 @@
module.exports =
angular.module('trafficPortal.private.serverCapabilities.view', [])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
- .state('trafficPortal.private.serverCapabilities.view',
{
- url: '/{serverCapability}',
+ .state('trafficPortal.private.serverCapabilities.edit',
{
+ url: '/edit?name',
views: {
serverCapabilitiesContent: {
templateUrl:
'common/modules/form/serverCapability/form.serverCapability.tpl.html',
- controller:
'FormViewServerCapabilityController',
+ controller:
'FormEditServerCapabilityController',
resolve: {
serverCapability:
function($stateParams, serverCapabilityService) {
- return
serverCapabilityService.getServerCapability($stateParams.serverCapability);
+ return
serverCapabilityService.getServerCapability($stateParams.name);
}
}
}
diff --git
a/traffic_portal/app/src/modules/private/serverCapabilities/servers/index.js
b/traffic_portal/app/src/modules/private/serverCapabilities/servers/index.js
index 51e578e..83cf046 100644
--- a/traffic_portal/app/src/modules/private/serverCapabilities/servers/index.js
+++ b/traffic_portal/app/src/modules/private/serverCapabilities/servers/index.js
@@ -21,17 +21,17 @@ module.exports =
angular.module('trafficPortal.private.serverCapabilities.server
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('trafficPortal.private.serverCapabilities.servers', {
- url: '/{serverCapability}/servers',
+ url: '/servers?name',
views: {
serverCapabilitiesContent: {
templateUrl:
'common/modules/table/serverCapabilityServers/table.serverCapabilityServers.tpl.html',
controller:
'TableServerCapabilityServersController',
resolve: {
serverCapability:
function($stateParams, serverCapabilityService) {
- return
serverCapabilityService.getServerCapability($stateParams.serverCapability);
+ return
serverCapabilityService.getServerCapability($stateParams.name);
},
servers:
function($stateParams, serverCapabilityService) {
- return
serverCapabilityService.getServerCapabilityServers($stateParams.serverCapability);
+ return
serverCapabilityService.getServerCapabilityServers($stateParams.name);
}
}
}
diff --git a/traffic_portal/test/end_to_end/serverCapabilities/pageData.js
b/traffic_portal/test/end_to_end/serverCapabilities/pageData.js
index 359941b..3e69548 100644
--- a/traffic_portal/test/end_to_end/serverCapabilities/pageData.js
+++ b/traffic_portal/test/end_to_end/serverCapabilities/pageData.js
@@ -20,6 +20,7 @@
module.exports = function(){
this.name=element(by.name('name'));
this.createButton=element(by.buttonText('Create'));
+ this.updateButton=element(by.buttonText('Update'));
this.deleteButton=element(by.buttonText('Delete'));
this.searchFilter=element(by.id('serverCapabilitiesTable_filter')).element(by.css('label
input'));
this.confirmWithNameInput=element(by.name('confirmWithNameInput'));
diff --git
a/traffic_portal/test/end_to_end/serverCapabilities/server-capabilities-spec.js
b/traffic_portal/test/end_to_end/serverCapabilities/server-capabilities-spec.js
index c6c5868..1f11a5b 100644
---
a/traffic_portal/test/end_to_end/serverCapabilities/server-capabilities-spec.js
+++
b/traffic_portal/test/end_to_end/serverCapabilities/server-capabilities-spec.js
@@ -53,8 +53,8 @@ describe('Traffic Portal Server Capabilities Test Suite',
function() {
expect(browser.getCurrentUrl().then(commonFunctions.urlPath)).toEqual(commonFunctions.urlPath(browser.baseUrl)+"#!/server-capabilities");
});
- it('should view the new server capability', function() {
- console.log('Viewing the new server capability: ' +
myNewServerCap.name);
+ it('should edit an existing server capability', function() {
+ console.log('Editing an existing server capability: ' +
myNewServerCap.name);
pageData.searchFilter.sendKeys(myNewServerCap.name);
element.all(by.repeater('sc in
::serverCapabilities')).filter(function(row){
return
row.element(by.name('name')).getText().then(function(val){
@@ -62,6 +62,10 @@ describe('Traffic Portal Server Capabilities Test Suite',
function() {
});
}).get(0).click();
expect(pageData.name.getText() === myNewServerCap.name);
+ expect(pageData.updateButton.isEnabled()).toBe(false);
+ pageData.name.sendKeys("-updated");
+ expect(pageData.updateButton.isEnabled()).toBe(true);
+ expect(pageData.name.getText() ===
myNewServerCap.name+"-updated");
});
});