This is an automated email from the ASF dual-hosted git repository.

ocket8888 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 b4183c8dea Delivery Service Regional field: Optionally make Max Origin 
Connections per Cache Group (#7111)
b4183c8dea is described below

commit b4183c8dea698112441333bf9c9598b3dd622280
Author: Zach Hoffman <[email protected]>
AuthorDate: Tue Oct 11 22:09:52 2022 +0000

    Delivery Service Regional field: Optionally make Max Origin Connections per 
Cache Group (#7111)
    
    * Mock DS row from an array of key/value pairs instead of 2 separate arrays
    
    * Delivery Service Regional field: Optionally make Max Origin Connections 
per Cache Group
    
    * Set `regional` field in deliveryservice_requests table where it does not 
exist
    
    * Add Regional field to Traffic Portal v1
    
    * Specify what the `regional` field was added to
    
    * Check for NULL on the deliveryservice field too
    
    * Unindent note
    
    * Do not check for NULL
    
    * Make regional field a checkbox
    
    * Specify what object `regional` field was added to
    
    * Define remap.config location parameter to avoid ISE when
    maxOriginConnections is nonzero
    
    * Only set maxOriginConnections and regional fields for DeliveryServices 
tests
    
    * Create remap.config location parameter before creating a Delivery
    Service with nonzero maxOriginConnections
    
    * Do not randomize remap.config location parameter
    
    * Check if data.noRandomize is true, not just whether it exists
---
 CHANGELOG.md                                       |   1 +
 docs/source/api/v4/deliveryservice_requests.rst    |   7 +
 .../api/v4/deliveryservice_requests_id_assign.rst  |   2 +
 .../api/v4/deliveryservice_requests_id_status.rst  |   2 +
 docs/source/api/v4/deliveryservices.rst            |   6 +
 docs/source/api/v4/deliveryservices_id.rst         |   4 +
 docs/source/api/v4/deliveryservices_id_safe.rst    |   2 +
 docs/source/api/v4/servers_id_deliveryservices.rst |   2 +
 docs/source/api/v5/deliveryservice_requests.rst    |   7 +
 .../api/v5/deliveryservice_requests_id_assign.rst  |   2 +
 .../api/v5/deliveryservice_requests_id_status.rst  |   2 +
 docs/source/api/v5/deliveryservices.rst            |   6 +
 docs/source/api/v5/deliveryservices_id.rst         |   4 +
 docs/source/api/v5/deliveryservices_id_safe.rst    |   2 +
 docs/source/api/v5/servers_id_deliveryservices.rst |   2 +
 docs/source/glossary.rst                           |   1 +
 docs/source/overview/delivery_services.rst         |   9 +
 lib/go-tc/deliveryservices.go                      |   4 +
 .../2022100210472946_ds_regional.down.sql          |  27 +++
 .../migrations/2022100210472946_ds_regional.up.sql |  29 +++
 .../testing/api/v4/deliveryservices_test.go        |   2 +
 .../testing/api/v5/deliveryservices_test.go        |   2 +
 .../deliveryservice/deliveryservices.go            | 103 ++++-----
 .../deliveryservice/deliveryservices_test.go       | 229 ++++++++-------------
 .../form.deliveryService.DNS.tpl.html              |  20 ++
 .../form.deliveryService.HTTP.tpl.html             |  20 ++
 .../TableDeliveryServicesController.js             |   5 +
 traffic_portal/test/integration/CommonUtils/API.ts |   2 +-
 .../test/integration/Data/deliveryservices.ts      |  16 ++
 traffic_portal/test/integration/Data/jobs.ts       |   2 +-
 30 files changed, 330 insertions(+), 192 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b24e6bba9..cddf67f49f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - [#2101](https://github.com/apache/trafficcontrol/issues/2101) *Traffic 
Portal* Added the ability to tell if a Delivery Service is the target of 
another steering DS.
 - [#6033](https://github.com/apache/trafficcontrol/issues/6033) *Traffic Ops, 
Traffic Portal* Added ability to assign multiple server capabilities to a 
server.
 - [#7032](https://github.com/apache/trafficcontrol/issues/7032) *Cache Config* 
Add t3c-apply flag to use local ATS version for config generation rather than 
Server package Parameter, to allow managing the ATS OS package via external 
tools. See 'man t3c-apply' and 'man t3c-generate' for details.
+- [#7097](https://github.com/apache/trafficcontrol/issues/7097) *Traffic Ops, 
Traffic Portal* Added the `regional` field to Delivery Services, which 
indicates whether `maxOriginConnections` should be per Cache Group
 
 ### Changed
 - [#7063](https://github.com/apache/trafficcontrol/pull/7063) *Traffic Ops* 
Python client now uses Traffic Ops API 4.1 by default.
diff --git a/docs/source/api/v4/deliveryservice_requests.rst 
b/docs/source/api/v4/deliveryservice_requests.rst
index 084164c58b..dd628cd4d3 100644
--- a/docs/source/api/v4/deliveryservice_requests.rst
+++ b/docs/source/api/v4/deliveryservice_requests.rst
@@ -160,6 +160,7 @@ The response is an array of representations of 
:term:`Delivery Service Requests`
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -276,6 +277,7 @@ The request must be a well-formed representation of a 
:term:`Delivery Service Re
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -400,6 +402,7 @@ The response will be a representation of the created 
:term:`Delivery Service Req
                                "qstringIgnore": 0,
                                "rangeRequestHandling": 0,
                                "regexRemap": null,
+                               "regional": false,
                                "regionalGeoBlocking": false,
                                "remapText": null,
                                "routingName": "video",
@@ -484,6 +487,7 @@ The response will be a representation of the created 
:term:`Delivery Service Req
                                "qstringIgnore": 0,
                                "rangeRequestHandling": 0,
                                "regexRemap": null,
+                               "regional": false,
                                "regionalGeoBlocking": false,
                                "remapText": null,
                                "routingName": "video",
@@ -568,6 +572,7 @@ The request body must be a representation of a 
:term:`Delivery Service Request`
                        "initialDispersion": 3,
                        "logsEnabled": false,
                        "longDesc": "long desc",
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "tenantId": 1,
                        "typeId": 8,
@@ -659,6 +664,7 @@ The response is a full representation of the edited 
:term:`Delivery Service Requ
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -739,6 +745,7 @@ The response is a full representation of the edited 
:term:`Delivery Service Requ
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v4/deliveryservice_requests_id_assign.rst 
b/docs/source/api/v4/deliveryservice_requests_id_assign.rst
index ceab2da19a..9a9710acec 100644
--- a/docs/source/api/v4/deliveryservice_requests_id_assign.rst
+++ b/docs/source/api/v4/deliveryservice_requests_id_assign.rst
@@ -195,6 +195,7 @@ The response contains a full representation of the newly 
assigned :term:`Deliver
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -275,6 +276,7 @@ The response contains a full representation of the newly 
assigned :term:`Deliver
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v4/deliveryservice_requests_id_status.rst 
b/docs/source/api/v4/deliveryservice_requests_id_status.rst
index 2238bf30d2..933e8abe25 100644
--- a/docs/source/api/v4/deliveryservice_requests_id_status.rst
+++ b/docs/source/api/v4/deliveryservice_requests_id_status.rst
@@ -192,6 +192,7 @@ The response is a full representation of the modified 
:term:`DSR`.
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -272,6 +273,7 @@ The response is a full representation of the modified 
:term:`DSR`.
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v4/deliveryservices.rst 
b/docs/source/api/v4/deliveryservices.rst
index 2e1ff81a73..f6e3934d9b 100644
--- a/docs/source/api/v4/deliveryservices.rst
+++ b/docs/source/api/v4/deliveryservices.rst
@@ -145,6 +145,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -246,6 +247,7 @@ Response Structure
                        "rangeRequestHandling": 0,
                        "rangeSliceBlockSize": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -323,6 +325,7 @@ Request Structure
 :qstringIgnore:             An integral, unique identifier that corresponds to 
the :ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:      An integral, unique identifier that corresponds to 
the :ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:                A :ref:`ds-regex-remap`
+:regional:                  A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:       A boolean defining the :ref:`ds-regionalgeo` 
setting on this :term:`Delivery Service`
 :remapText:                 :ref:`ds-raw-remap`
 :serviceCategory:           The name of the :ref:`ds-service-category` with 
which the :term:`Delivery Service` is associated - or ``null`` if there is to 
be no such category
@@ -402,6 +405,7 @@ Request Structure
                "qstringIgnore": 0,
                "rangeRequestHandling": 0,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "routingName": "test",
                "serviceCategory": null,
@@ -488,6 +492,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -598,6 +603,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "test",
diff --git a/docs/source/api/v4/deliveryservices_id.rst 
b/docs/source/api/v4/deliveryservices_id.rst
index c946ee62fa..c2ce373d9f 100644
--- a/docs/source/api/v4/deliveryservices_id.rst
+++ b/docs/source/api/v4/deliveryservices_id.rst
@@ -78,6 +78,7 @@ Request Structure
 :qstringIgnore:             An integral, unique identifier that corresponds to 
the :ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:      An integral, unique identifier that corresponds to 
the :ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:                A :ref:`ds-regex-remap`
+:regional:                  A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:       A boolean defining the :ref:`ds-regionalgeo` 
setting on this :term:`Delivery Service`
 :remapText:                 :ref:`ds-raw-remap`
 :routingName:               The :ref:`ds-routing-name` of this :term:`Delivery 
Service`
@@ -162,6 +163,7 @@ Request Structure
                "qstringIgnore": 0,
                "rangeRequestHandling": 0,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "routingName": "test",
                "serviceCategory": null,
@@ -245,6 +247,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -349,6 +352,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "test",
diff --git a/docs/source/api/v4/deliveryservices_id_safe.rst 
b/docs/source/api/v4/deliveryservices_id_safe.rst
index 147bc9eda8..8bafe33110 100644
--- a/docs/source/api/v4/deliveryservices_id_safe.rst
+++ b/docs/source/api/v4/deliveryservices_id_safe.rst
@@ -123,6 +123,7 @@ Response Structure
 :qstringIgnore:        An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling: An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:           A :ref:`ds-regex-remap`
+:regional:             A boolean value defining the :ref:`ds-regional` setting 
on this :term:`Delivery Service`
 :regionalGeoBlocking:  A boolean defining the :ref:`ds-regionalgeo` setting on 
this :term:`Delivery Service`
 :remapText:            :ref:`ds-raw-remap`
 :signed:               ``true`` if  and only if ``signingAlgorithm`` is not 
``null``, ``false`` otherwise
@@ -223,6 +224,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "video",
diff --git a/docs/source/api/v4/servers_id_deliveryservices.rst 
b/docs/source/api/v4/servers_id_deliveryservices.rst
index 3f584811c1..386de7532a 100644
--- a/docs/source/api/v4/servers_id_deliveryservices.rst
+++ b/docs/source/api/v4/servers_id_deliveryservices.rst
@@ -131,6 +131,7 @@ Response Structure
 :qstringIgnore:        An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling: An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:           A :ref:`ds-regex-remap`
+:regional:             A boolean value defining the :ref:`ds-regional` setting 
on this :term:`Delivery Service`
 :regionalGeoBlocking:  A boolean defining the :ref:`ds-regionalgeo` setting on 
this :term:`Delivery Service`
 :remapText:            :ref:`ds-raw-remap`
 :signed:               ``true`` if  and only if ``signingAlgorithm`` is not 
``null``, ``false`` otherwise
@@ -230,6 +231,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "cdn",
diff --git a/docs/source/api/v5/deliveryservice_requests.rst 
b/docs/source/api/v5/deliveryservice_requests.rst
index a3c62ddc35..e9f0fc1c9b 100644
--- a/docs/source/api/v5/deliveryservice_requests.rst
+++ b/docs/source/api/v5/deliveryservice_requests.rst
@@ -160,6 +160,7 @@ The response is an array of representations of 
:term:`Delivery Service Requests`
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -276,6 +277,7 @@ The request must be a well-formed representation of a 
:term:`Delivery Service Re
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -400,6 +402,7 @@ The response will be a representation of the created 
:term:`Delivery Service Req
                                "qstringIgnore": 0,
                                "rangeRequestHandling": 0,
                                "regexRemap": null,
+                               "regional": false,
                                "regionalGeoBlocking": false,
                                "remapText": null,
                                "routingName": "video",
@@ -484,6 +487,7 @@ The response will be a representation of the created 
:term:`Delivery Service Req
                                "qstringIgnore": 0,
                                "rangeRequestHandling": 0,
                                "regexRemap": null,
+                               "regional": false,
                                "regionalGeoBlocking": false,
                                "remapText": null,
                                "routingName": "video",
@@ -568,6 +572,7 @@ The request body must be a representation of a 
:term:`Delivery Service Request`
                        "initialDispersion": 3,
                        "logsEnabled": false,
                        "longDesc": "long desc",
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "tenantId": 1,
                        "typeId": 8,
@@ -659,6 +664,7 @@ The response is a full representation of the edited 
:term:`Delivery Service Requ
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -739,6 +745,7 @@ The response is a full representation of the edited 
:term:`Delivery Service Requ
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v5/deliveryservice_requests_id_assign.rst 
b/docs/source/api/v5/deliveryservice_requests_id_assign.rst
index 660c05a737..389bcab17e 100644
--- a/docs/source/api/v5/deliveryservice_requests_id_assign.rst
+++ b/docs/source/api/v5/deliveryservice_requests_id_assign.rst
@@ -188,6 +188,7 @@ The response contains a full representation of the newly 
assigned :term:`Deliver
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -268,6 +269,7 @@ The response contains a full representation of the newly 
assigned :term:`Deliver
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v5/deliveryservice_requests_id_status.rst 
b/docs/source/api/v5/deliveryservice_requests_id_status.rst
index c01cc9c77b..436fa6799b 100644
--- a/docs/source/api/v5/deliveryservice_requests_id_status.rst
+++ b/docs/source/api/v5/deliveryservice_requests_id_status.rst
@@ -190,6 +190,7 @@ The response is a full representation of the modified 
:term:`DSR`.
                        "qstringIgnore": 0,
                        "rangeRequestHandling": 0,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -270,6 +271,7 @@ The response is a full representation of the modified 
:term:`DSR`.
                        "qstringIgnore": null,
                        "rangeRequestHandling": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "cdn",
diff --git a/docs/source/api/v5/deliveryservices.rst 
b/docs/source/api/v5/deliveryservices.rst
index 35e592ee2a..407fb3691e 100644
--- a/docs/source/api/v5/deliveryservices.rst
+++ b/docs/source/api/v5/deliveryservices.rst
@@ -141,6 +141,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -239,6 +240,7 @@ Response Structure
                        "rangeRequestHandling": 0,
                        "rangeSliceBlockSize": null,
                        "regexRemap": null,
+                       "regional": false,
                        "regionalGeoBlocking": false,
                        "remapText": null,
                        "routingName": "video",
@@ -316,6 +318,7 @@ Request Structure
 :qstringIgnore:             An integral, unique identifier that corresponds to 
the :ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:      An integral, unique identifier that corresponds to 
the :ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:                A :ref:`ds-regex-remap`
+:regional:                  A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:       A boolean defining the :ref:`ds-regionalgeo` 
setting on this :term:`Delivery Service`
 :remapText:                 :ref:`ds-raw-remap`
 :serviceCategory:           The name of the :ref:`ds-service-category` with 
which the :term:`Delivery Service` is associated - or ``null`` if there is to 
be no such category
@@ -392,6 +395,7 @@ Request Structure
                "qstringIgnore": 0,
                "rangeRequestHandling": 0,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "routingName": "test",
                "serviceCategory": null,
@@ -474,6 +478,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -581,6 +586,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "test",
diff --git a/docs/source/api/v5/deliveryservices_id.rst 
b/docs/source/api/v5/deliveryservices_id.rst
index 97f66e9205..d2f28f5518 100644
--- a/docs/source/api/v5/deliveryservices_id.rst
+++ b/docs/source/api/v5/deliveryservices_id.rst
@@ -78,6 +78,7 @@ Request Structure
 :qstringIgnore:             An integral, unique identifier that corresponds to 
the :ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:      An integral, unique identifier that corresponds to 
the :ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:                A :ref:`ds-regex-remap`
+:regional:                  A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:       A boolean defining the :ref:`ds-regionalgeo` 
setting on this :term:`Delivery Service`
 :remapText:                 :ref:`ds-raw-remap`
 :routingName:               The :ref:`ds-routing-name` of this :term:`Delivery 
Service`
@@ -158,6 +159,7 @@ Request Structure
                "qstringIgnore": 0,
                "rangeRequestHandling": 0,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "routingName": "test",
                "serviceCategory": null,
@@ -237,6 +239,7 @@ Response Structure
 :qstringIgnore:         An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling:  An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:            A :ref:`ds-regex-remap`
+:regional:              A boolean value defining the :ref:`ds-regional` 
setting on this :term:`Delivery Service`
 :regionalGeoBlocking:   A boolean defining the :ref:`ds-regionalgeo` setting 
on this :term:`Delivery Service`
 :remapText:             :ref:`ds-raw-remap`
 :serviceCategory:       The name of the :ref:`ds-service-category` with which 
the :term:`Delivery Service` is associated
@@ -338,6 +341,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "test",
diff --git a/docs/source/api/v5/deliveryservices_id_safe.rst 
b/docs/source/api/v5/deliveryservices_id_safe.rst
index 84b3edc629..525384607d 100644
--- a/docs/source/api/v5/deliveryservices_id_safe.rst
+++ b/docs/source/api/v5/deliveryservices_id_safe.rst
@@ -119,6 +119,7 @@ Response Structure
 :qstringIgnore:        An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling: An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:           A :ref:`ds-regex-remap`
+:regional:             A boolean value defining the :ref:`ds-regional` setting 
on this :term:`Delivery Service`
 :regionalGeoBlocking:  A boolean defining the :ref:`ds-regionalgeo` setting on 
this :term:`Delivery Service`
 :remapText:            :ref:`ds-raw-remap`
 :signed:               ``true`` if  and only if ``signingAlgorithm`` is not 
``null``, ``false`` otherwise
@@ -216,6 +217,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "video",
diff --git a/docs/source/api/v5/servers_id_deliveryservices.rst 
b/docs/source/api/v5/servers_id_deliveryservices.rst
index e6f1d74f6f..3e6c01bfaa 100644
--- a/docs/source/api/v5/servers_id_deliveryservices.rst
+++ b/docs/source/api/v5/servers_id_deliveryservices.rst
@@ -127,6 +127,7 @@ Response Structure
 :qstringIgnore:        An integral, unique identifier that corresponds to the 
:ref:`ds-qstring-handling` setting on this :term:`Delivery Service`
 :rangeRequestHandling: An integral, unique identifier that corresponds to the 
:ref:`ds-range-request-handling` setting on this :term:`Delivery Service`
 :regexRemap:           A :ref:`ds-regex-remap`
+:regional:             A boolean value defining the :ref:`ds-regional` setting 
on this :term:`Delivery Service`
 :regionalGeoBlocking:  A boolean defining the :ref:`ds-regionalgeo` setting on 
this :term:`Delivery Service`
 :remapText:            :ref:`ds-raw-remap`
 :signed:               ``true`` if  and only if ``signingAlgorithm`` is not 
``null``, ``false`` otherwise
@@ -223,6 +224,7 @@ Response Structure
                "rangeRequestHandling": 0,
                "rangeSliceBlockSize": null,
                "regexRemap": null,
+               "regional": false,
                "regionalGeoBlocking": false,
                "remapText": null,
                "routingName": "cdn",
diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst
index 9e89396f71..5e5a08380d 100644
--- a/docs/source/glossary.rst
+++ b/docs/source/glossary.rst
@@ -32,6 +32,7 @@ Glossary
                An :abbr:`ATS (Apache Traffic Server)` plugin that allows you 
to monitor vitals of the :abbr:`ATS (Apache Traffic Server)` server. See 
:ref:`astats`.
 
        Cache Server
+       Cache Servers
        cache server
        cache servers
                The main function of a CDN is to proxy requests from clients to 
:term:`origin servers` and cache the results. To proxy, in the CDN context, is 
to obtain content using HTTP from an :term:`origin server` on behalf of a 
client. To cache is to store the results so they can be reused when other 
clients are requesting the same content. There are three types of proxies in 
use on the Internet today:
diff --git a/docs/source/overview/delivery_services.rst 
b/docs/source/overview/delivery_services.rst
index 79be7168f2..c0484e1b42 100644
--- a/docs/source/overview/delivery_services.rst
+++ b/docs/source/overview/delivery_services.rst
@@ -505,6 +505,9 @@ Max Origin Connections
 ----------------------
 The maximum number of TCP connections individual :term:`Mid-tier cache 
servers` are allowed to make to the `Origin Server Base URL`. A value of ``0`` 
in this field indicates that there is no maximum.
 
+
+.. note:: Max Origin Connections can be made per-:ref:`Cache Group 
<cache-groups>` by setting the :ref:`ds-regional` field.
+
 .. _ds-max-request-header-bytes:
 
 Max Request Header Bytes
@@ -717,6 +720,12 @@ Allows remapping of incoming requests URL using regular 
expressions to search an
        | regexRemap | Traffic Ops source code and database, and :ref:`to-api` 
requests/responses | unchanged (``string`` etc.) |
        
+------------+----------------------------------------------------------------------------+-----------------------------+
 
+.. _ds-regional:
+
+Regional
+--------
+A boolean value. If a Delivery Service is Regional (``true``), then 
:ref:`ds-max-origin-connections` is per :ref:`Cache Group <cache-groups>`, 
rather than divided over all :term:`Cache Servers` in child Cache Groups of the 
:term:`Origin` (``false``, the default).
+
 .. _ds-regionalgeo:
 
 Regional Geoblocking
diff --git a/lib/go-tc/deliveryservices.go b/lib/go-tc/deliveryservices.go
index 00490777dc..64c8353578 100644
--- a/lib/go-tc/deliveryservices.go
+++ b/lib/go-tc/deliveryservices.go
@@ -243,6 +243,10 @@ type DeliveryServiceV40 struct {
        DeliveryServiceFieldsV13
        DeliveryServiceNullableFieldsV11
 
+       // Regional indicates whether the Delivery Service's 
MaxOriginConnections is
+       // only per Cache Group, rather than divided over all Cache Servers in 
child
+       // Cache Groups of the Origin.
+       Regional bool `json:"regional" db:"regional"`
        // TLSVersions is the list of explicitly supported TLS versions for 
cache
        // servers serving the Delivery Service's content.
        TLSVersions       []string              `json:"tlsVersions" 
db:"tls_versions"`
diff --git 
a/traffic_ops/app/db/migrations/2022100210472946_ds_regional.down.sql 
b/traffic_ops/app/db/migrations/2022100210472946_ds_regional.down.sql
new file mode 100644
index 0000000000..d512079437
--- /dev/null
+++ b/traffic_ops/app/db/migrations/2022100210472946_ds_regional.down.sql
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership.  The ASF
+ * licenses this file to you 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.
+ */
+
+ALTER TABLE public.deliveryservice
+DROP COLUMN regional;
+
+/* Remove `regional` from deliveryservice */
+UPDATE public.deliveryservice_request
+SET deliveryservice = deliveryservice - 'regional';
+
+/* Remove `regional` from original */
+UPDATE public.deliveryservice_request
+SET original = original - 'regional';
diff --git a/traffic_ops/app/db/migrations/2022100210472946_ds_regional.up.sql 
b/traffic_ops/app/db/migrations/2022100210472946_ds_regional.up.sql
new file mode 100644
index 0000000000..4bca8e3b9e
--- /dev/null
+++ b/traffic_ops/app/db/migrations/2022100210472946_ds_regional.up.sql
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership.  The ASF
+ * licenses this file to you 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.
+ */
+
+ALTER TABLE public.deliveryservice
+ADD COLUMN regional BOOLEAN NOT NULL DEFAULT FALSE;
+
+/* Set `regional` to `false` if it does not exist */
+UPDATE public.deliveryservice_request
+SET deliveryservice = deliveryservice || '{"regional": false}'
+WHERE deliveryservice->>'regional' IS NULL;
+
+/* Set `regional` to `false` it does not exist and `original` is not null */
+UPDATE public.deliveryservice_request
+SET original = original || '{"regional": false}'
+WHERE original->>'regional' IS NULL;
diff --git a/traffic_ops/testing/api/v4/deliveryservices_test.go 
b/traffic_ops/testing/api/v4/deliveryservices_test.go
index b94c509255..e4baa3a60e 100644
--- a/traffic_ops/testing/api/v4/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v4/deliveryservices_test.go
@@ -281,6 +281,7 @@ func TestDeliveryServices(t *testing.T) {
                                                "multiSiteOrigin":       true,
                                                "orgServerFqdn":         
"http://origin.example.net";,
                                                "protocol":              2,
+                                               "regional":              true,
                                                "routingName":           
"ccr-ds2",
                                                "qStringIgnore":         0,
                                                "regionalGeoBlocking":   true,
@@ -736,6 +737,7 @@ func generateDeliveryService(t *testing.T, requestDS 
map[string]interface{}) map
                "profileName":          "ATS_EDGE_TIER_CACHE",
                "qstringIgnore":        0,
                "rangeRequestHandling": 0,
+               "regional":             false,
                "regionalGeoBlocking":  false,
                "routingName":          "ccr-ds1",
                "tenant":               "tenant1",
diff --git a/traffic_ops/testing/api/v5/deliveryservices_test.go 
b/traffic_ops/testing/api/v5/deliveryservices_test.go
index 830df157a8..bf3bb1c02c 100644
--- a/traffic_ops/testing/api/v5/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v5/deliveryservices_test.go
@@ -281,6 +281,7 @@ func TestDeliveryServices(t *testing.T) {
                                                "multiSiteOrigin":       true,
                                                "orgServerFqdn":         
"http://origin.example.net";,
                                                "protocol":              2,
+                                               "regional":              true,
                                                "routingName":           
"ccr-ds2",
                                                "qStringIgnore":         0,
                                                "regionalGeoBlocking":   true,
@@ -736,6 +737,7 @@ func generateDeliveryService(t *testing.T, requestDS 
map[string]interface{}) map
                "profileName":          "ATS_EDGE_TIER_CACHE",
                "qstringIgnore":        0,
                "rangeRequestHandling": 0,
+               "regional":             false,
                "regionalGeoBlocking":  false,
                "routingName":          "ccr-ds1",
                "tenant":               "tenant1",
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
index 8d3d197d09..7235c08649 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices.go
@@ -338,6 +338,7 @@ func createV40(w http.ResponseWriter, r *http.Request, inf 
*api.APIInfo, dsV40 t
                        &ds.QStringIgnore,
                        &ds.RangeRequestHandling,
                        &ds.RegexRemap,
+                       &ds.Regional,
                        &ds.RegionalGeoBlocking,
                        &ds.RemapText,
                        &ds.RoutingName,
@@ -400,6 +401,7 @@ func createV40(w http.ResponseWriter, r *http.Request, inf 
*api.APIInfo, dsV40 t
                        &ds.QStringIgnore,
                        &ds.RangeRequestHandling,
                        &ds.RegexRemap,
+                       &ds.Regional,
                        &ds.RegionalGeoBlocking,
                        &ds.RemapText,
                        &ds.RoutingName,
@@ -867,6 +869,7 @@ func updateV40(w http.ResponseWriter, r *http.Request, inf 
*api.APIInfo, dsV40 *
                        &ds.QStringIgnore,
                        &ds.RangeRequestHandling,
                        &ds.RegexRemap,
+                       &ds.Regional,
                        &ds.RegionalGeoBlocking,
                        &ds.RemapText,
                        &ds.RoutingName,
@@ -929,6 +932,7 @@ func updateV40(w http.ResponseWriter, r *http.Request, inf 
*api.APIInfo, dsV40 *
                        &ds.QStringIgnore,
                        &ds.RangeRequestHandling,
                        &ds.RegexRemap,
+                       &ds.Regional,
                        &ds.RegionalGeoBlocking,
                        &ds.RemapText,
                        &ds.RoutingName,
@@ -1258,6 +1262,7 @@ func Validate(tx *sql.Tx, ds *tc.DeliveryServiceV4) error 
{
                "geoProvider":         validation.Validate(ds.GeoProvider, 
validation.NotNil),
                "httpByPassFqdn":      validation.Validate(ds.HTTPBypassFQDN, 
isDNSName),
                "logsEnabled":         validation.Validate(ds.LogsEnabled, 
validation.NotNil),
+               "regional":            validation.Validate(ds.Regional, 
validation.NotNil),
                "regionalGeoBlocking": 
validation.Validate(ds.RegionalGeoBlocking, validation.NotNil),
                "remapText":           validation.Validate(ds.RemapText, 
noLineBreaks),
                "routingName":         validation.Validate(ds.RoutingName, 
isDNSName, noPeriods, validation.Length(1, 48)),
@@ -1637,6 +1642,7 @@ func GetDeliveryServices(query string, queryValues 
map[string]interface{}, tx *s
                        pq.Array(&dsQueryParams),
                        &ds.RangeRequestHandling,
                        &ds.RegexRemap,
+                       &ds.Regional,
                        &ds.RegionalGeoBlocking,
                        &ds.RemapText,
                        &ds.RoutingName,
@@ -2175,6 +2181,7 @@ ds.active,
                                WHERE deliveryservice_id = ds.id) AS query_keys,
        ds.range_request_handling,
        ds.regex_remap,
+       ds.regional,
        ds.regional_geo_blocking,
        ds.remap_text,
        ds.routing_name,
@@ -2241,28 +2248,29 @@ protocol=$35,
 qstring_ignore=$36,
 range_request_handling=$37,
 regex_remap=$38,
-regional_geo_blocking=$39,
-remap_text=$40,
-routing_name=$41,
-signing_algorithm=$42,
-ssl_key_version=$43,
-tenant_id=$44,
-tr_request_headers=$45,
-tr_response_headers=$46,
-type=$47,
-xml_id=$48,
-anonymous_blocking_enabled=$49,
-consistent_hash_regex=$50,
-max_origin_connections=$51,
-ecs_enabled=$52,
-range_slice_block_size=$53,
-topology=$54,
-first_header_rewrite=$55,
-inner_header_rewrite=$56,
-last_header_rewrite=$57,
-service_category=$58,
-max_request_header_bytes=$59
-WHERE id=$60
+regional=$39,
+regional_geo_blocking=$40,
+remap_text=$41,
+routing_name=$42,
+signing_algorithm=$43,
+ssl_key_version=$44,
+tenant_id=$45,
+tr_request_headers=$46,
+tr_response_headers=$47,
+type=$48,
+xml_id=$49,
+anonymous_blocking_enabled=$50,
+consistent_hash_regex=$51,
+max_origin_connections=$52,
+ecs_enabled=$53,
+range_slice_block_size=$54,
+topology=$55,
+first_header_rewrite=$56,
+inner_header_rewrite=$57,
+last_header_rewrite=$58,
+service_category=$59,
+max_request_header_bytes=$60
+WHERE id=$61
 RETURNING last_updated
 `
 }
@@ -2307,28 +2315,29 @@ protocol=$33,
 qstring_ignore=$34,
 range_request_handling=$35,
 regex_remap=$36,
-regional_geo_blocking=$37,
-remap_text=$38,
-routing_name=$39,
-signing_algorithm=$40,
-ssl_key_version=$41,
-tenant_id=$42,
-tr_request_headers=$43,
-tr_response_headers=$44,
-type=$45,
-xml_id=$46,
-anonymous_blocking_enabled=$47,
-consistent_hash_regex=$48,
-max_origin_connections=$49,
-ecs_enabled=$50,
-range_slice_block_size=$51,
-topology=$52,
-first_header_rewrite=$53,
-inner_header_rewrite=$54,
-last_header_rewrite=$55,
-service_category=$56,
-max_request_header_bytes=$57
-WHERE id=$58
+regional=$37,
+regional_geo_blocking=$38,
+remap_text=$39,
+routing_name=$40,
+signing_algorithm=$41,
+ssl_key_version=$42,
+tenant_id=$43,
+tr_request_headers=$44,
+tr_response_headers=$45,
+type=$46,
+xml_id=$47,
+anonymous_blocking_enabled=$48,
+consistent_hash_regex=$49,
+max_origin_connections=$50,
+ecs_enabled=$51,
+range_slice_block_size=$52,
+topology=$53,
+first_header_rewrite=$54,
+inner_header_rewrite=$55,
+last_header_rewrite=$56,
+service_category=$57,
+max_request_header_bytes=$58
+WHERE id=$59
 RETURNING last_updated
 `
 }
@@ -2377,6 +2386,7 @@ protocol,
 qstring_ignore,
 range_request_handling,
 regex_remap,
+regional,
 regional_geo_blocking,
 remap_text,
 routing_name,
@@ -2396,7 +2406,7 @@ last_header_rewrite,
 service_category,
 max_request_header_bytes
 )
-VALUES 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59)
+VALUES 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60)
 RETURNING id, last_updated
 `
 }
@@ -2443,6 +2453,7 @@ protocol,
 qstring_ignore,
 range_request_handling,
 regex_remap,
+regional,
 regional_geo_blocking,
 remap_text,
 routing_name,
@@ -2462,7 +2473,7 @@ last_header_rewrite,
 service_category,
 max_request_header_bytes
 )
-VALUES 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57)
+VALUES 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58)
 RETURNING id, last_updated
 `
 }
diff --git 
a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices_test.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices_test.go
index 5498c8ea30..7bfaeaa876 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservices_test.go
@@ -20,6 +20,7 @@ package deliveryservice
  */
 
 import (
+       "database/sql/driver"
        "fmt"
        "net/http"
        "reflect"
@@ -259,154 +260,94 @@ func TestReadGetDeliveryServices(t *testing.T) {
                TenantID: 1,
        }
 
+       dsRow := []struct {
+               key   string
+               value driver.Value
+       }{
+               {"active", true},
+               {"anonymous_blocking_enabled", false},
+               {"ccr_dns_ttl", nil},
+               {"cdn_id", 1},
+               {"cdnName", "test"},
+               {"check_path", ""},
+               {"consistent_hash_regex", ""},
+               {"deep_caching_type", "NEVER"},
+               {"display_name", "Demo 1"},
+               {"dns_bypass_cname", nil},
+               {"dns_bypass_ip", nil},
+               {"dns_bypass_ip6", nil},
+               {"dns_bypass_ttl", nil},
+               {"dscp", 1},
+               {"ecs_enabled", false},
+               {"edge_header_rewrite", nil},
+               {"first_header_rewrite", nil},
+               {"geolimit_redirect_url", nil},
+               {"geo_limit", 0},
+               {"geo_limit_countries", nil},
+               {"geo_provider", 0},
+               {"global_max_mbps", nil},
+               {"global_max_tps", nil},
+               {"fq_pacing_rate", nil},
+               {"http_bypass_fqdn", nil},
+               {"id", 1},
+               {"info_url", nil},
+               {"initial_dispersion", 1},
+               {"inner_header_rewrite", nil},
+               {"ipv6_routing_enabled", true},
+               {"last_header_rewrite", nil},
+               {"last_updated", time.Now()},
+               {"logs_enabled", false},
+               {"long_desc", nil},
+               {"long_desc_1", nil},
+               {"long_desc_2", nil},
+               {"max_dns_answers", nil},
+               {"max_origin_connections", nil},
+               {"max_request_header_bytes", nil},
+               {"mid_header_rewrite", nil},
+               {"miss_lat", 0.0},
+               {"miss_long", 0.0},
+               {"multi_site_origin", false},
+               {"org_server_fqdn", "origin.infra.ciab.test"},
+               {"origin_shield", nil},
+               {"profileID", nil},
+               {"profile_name", nil},
+               {"profile_description", nil},
+               {"protocol", 0},
+               {"qstring_ignore", 0},
+               {"query_keys", "{}"},
+               {"range_request_handling", 0},
+               {"regex_remap", nil},
+               {"regional", false},
+               {"regional_geo_blocking", false},
+               {"remap_text", nil},
+               {"routing_name", "video"},
+               {"service_category", nil},
+               {"signing_algorithm", nil},
+               {"range_slice_block_size", nil},
+               {"ssl_key_version", nil},
+               {"tenant_id", 1},
+               {"tenant.name", "test"},
+               {"tls_versions", "{}"},
+               {"topology", nil},
+               {"tr_request_headers", nil},
+               {"tr_response_headers", nil},
+               {"name", "test"},
+               {"type_id", 1},
+               {"xml_id", "demo1"},
+               {"cdn_domain", "mycdn.ciab.test"},
+       }
+       keys, values := []string{}, []driver.Value{}
+       for _, cell := range dsRow {
+               keys = append(keys, cell.key)
+               values = append(values, cell.value)
+       }
+
        mock.ExpectBegin()
        tenantRows := sqlmock.NewRows([]string{"id"})
        tenantRows.AddRow(u.TenantID)
        mock.ExpectQuery("WITH RECURSIVE").WillReturnRows(tenantRows)
-       dsRows := sqlmock.NewRows([]string{
-               "active",
-               "anonymous_blocking_enabled",
-               "ccr_dns_ttl",
-               "cdn_id",
-               "cdnName",
-               "check_path",
-               "consistent_hash_regex",
-               "deep_caching_type",
-               "display_name",
-               "dns_bypass_cname",
-               "dns_bypass_ip",
-               "dns_bypass_ip6",
-               "dns_bypass_ttl",
-               "dscp",
-               "ecs_enabled",
-               "edge_header_rewrite",
-               "first_header_rewrite",
-               "geolimit_redirect_url",
-               "geo_limit",
-               "geo_limit_countries",
-               "geo_provider",
-               "global_max_mbps",
-               "global_max_tps",
-               "fq_pacing_rate",
-               "http_bypass_fqdn",
-               "id",
-               "info_url",
-               "initial_dispersion",
-               "inner_header_rewrite",
-               "ipv6_routing_enabled",
-               "last_header_rewrite",
-               "last_updated",
-               "logs_enabled",
-               "long_desc",
-               "long_desc_1",
-               "long_desc_2",
-               "max_dns_answers",
-               "max_origin_connections",
-               "max_request_header_bytes",
-               "mid_header_rewrite",
-               "miss_lat",
-               "miss_long",
-               "multi_site_origin",
-               "org_server_fqdn",
-               "origin_shield",
-               "profileID",
-               "profile_name",
-               "profile_description",
-               "protocol",
-               "qstring_ignore",
-               "query_keys",
-               "range_request_handling",
-               "regex_remap",
-               "regional_geo_blocking",
-               "remap_text",
-               "routing_name",
-               "service_category",
-               "signing_algorithm",
-               "range_slice_block_size",
-               "ssl_key_version",
-               "tenant_id",
-               "tenant.name",
-               "tls_versions",
-               "topology",
-               "tr_request_headers",
-               "tr_response_headers",
-               "name",
-               "type_id",
-               "xml_id",
-               "cdn_domain",
-       })
-       dsRows.AddRow(
-               true,
-               false,
-               nil,
-               1,
-               "test",
-               "",
-               "",
-               "NEVER",
-               "Demo 1",
-               nil,
-               nil,
-               nil,
-               nil,
-               1,
-               false,
-               nil,
-               nil,
-               nil,
-               0,
-               nil,
-               0,
-               nil,
-               nil,
-               nil,
-               nil,
-               1,
-               nil,
-               1,
-               nil,
-               true,
-               nil,
-               time.Now(),
-               false,
-               nil,
-               nil,
-               nil,
-               nil,
-               nil,
-               nil,
-               nil,
-               0.0,
-               0.0,
-               false,
-               "origin.infra.ciab.test",
-               nil,
-               nil,
-               nil,
-               nil,
-               0,
-               0,
-               "{}",
-               0,
-               nil,
-               false,
-               nil,
-               "video",
-               nil,
-               nil,
-               nil,
-               nil,
-               1,
-               "test",
-               "{}",
-               nil,
-               nil,
-               nil,
-               "test",
-               1,
-               "demo1",
-               "mycdn.ciab.test",
-       )
+       dsRows := sqlmock.NewRows(keys)
+       dsRows.AddRow(values...)
        mock.ExpectQuery("^SELECT.*ORDER BY ds.xml_id$").WillReturnRows(dsRows)
        regexRows := sqlmock.NewRows([]string{"ds_name", "type", "pattern", 
"set_number"})
        regexRows.AddRow("demo1", "hostregexp", "", 0)
diff --git 
a/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.DNS.tpl.html
 
b/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.DNS.tpl.html
index d987c70d3f..c58676e5ae 100644
--- 
a/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.DNS.tpl.html
+++ 
b/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.DNS.tpl.html
@@ -483,6 +483,26 @@ under the License.
                             </aside>
                         </div>
                     </div>
+                    <div class="form-group">
+                        <label class="has-tooltip control-label col-md-2 
col-sm-2 col-xs-12" for="regional">
+                            Regional Max Origin Connections
+                            <div class="helptooltip">
+                                <div class="helptext">
+                                    If your Delivery Service is Regional, then 
you only expect it to be used by a single Cache Group. Enable this to make Max 
Origin Connections per Cache Group instead of a value used over all last-tier 
Cache Groups. <a 
href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#regional";
 target="_blank">See Regional Delivery Services</a>
+                                </div>
+                            </div>
+                        </label>
+                        <div class="col-md-10 col-sm-10 col-xs-12" 
style="display:inline-grid;grid-template-columns:auto;justify-content:start;">
+                            <input
+                                    type="checkbox"
+                                    id="regional"
+                                    name="regional"
+                                    class="form-control"
+                                    ng-model="deliveryService.regional"
+                                    style="max-width: max-content; min-width: 
1em;"
+                            />
+                        </div>
+                    </div>
                     <div class="form-group" ng-class="{'has-error': 
hasError(cacheConfig.maxRequestHeaderBytes), 'has-feedback': 
hasError(cacheConfig.maxRequestHeaderBytes)}">
                         <label class="has-tooltip control-label col-md-2 
col-sm-2 col-xs-12" for="maxRequestHeaderBytes">Max Request Header Bytes<div 
class="helptooltip">
                                 <div class="helptext">
diff --git 
a/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.HTTP.tpl.html
 
b/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.HTTP.tpl.html
index 8f63a94618..72e1bf5189 100644
--- 
a/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.HTTP.tpl.html
+++ 
b/traffic_portal/app/src/common/modules/form/deliveryService/form.deliveryService.HTTP.tpl.html
@@ -483,6 +483,26 @@ under the License.
                             </aside>
                         </div>
                     </div>
+                    <div class="form-group">
+                        <label class="has-tooltip control-label col-md-2 
col-sm-2 col-xs-12" for="regional">
+                            Regional Max Origin Connections
+                            <div class="helptooltip">
+                                <div class="helptext">
+                                    If your Delivery Service is Regional, then 
you only expect it to be used by a single Cache Group. Enable this to make Max 
Origin Connections per Cache Group instead of a value used over all last-tier 
Cache Groups. <a 
href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#regional";
 target="_blank">See Regional Delivery Services</a>
+                                </div>
+                            </div>
+                        </label>
+                        <div class="col-md-10 col-sm-10 col-xs-12" 
style="display:inline-grid;grid-template-columns:auto;justify-content:start;">
+                            <input
+                                    type="checkbox"
+                                    id="regional"
+                                    name="regional"
+                                    class="form-control"
+                                    ng-model="deliveryService.regional"
+                                    style="max-width: max-content; min-width: 
1em;"
+                            />
+                        </div>
+                    </div>
                     <div class="form-group" ng-class="{'has-error': 
hasError(cacheConfig.maxRequestHeaderBytes), 'has-feedback': 
hasError(cacheConfig.maxRequestHeaderBytes)}">
                         <label class="has-tooltip control-label col-md-2 
col-sm-2 col-xs-12" for="maxRequestHeaderBytes">Max Request Header Bytes<div 
class="helptooltip">
                                 <div class="helptext">
diff --git 
a/traffic_portal/app/src/common/modules/table/deliveryServices/TableDeliveryServicesController.js
 
b/traffic_portal/app/src/common/modules/table/deliveryServices/TableDeliveryServicesController.js
index d80fc2555b..3b10e100ac 100644
--- 
a/traffic_portal/app/src/common/modules/table/deliveryServices/TableDeliveryServicesController.js
+++ 
b/traffic_portal/app/src/common/modules/table/deliveryServices/TableDeliveryServicesController.js
@@ -283,6 +283,11 @@ function TableDeliveryServicesController(tableName, 
deliveryServices, steeringTa
                        field: "regexRemap",
                        hide: true
                },
+               {
+                       headerName: "Regional Max Origin Connections",
+                       field: "regional",
+                       hide: true
+               },
                {
                        headerName: "Regional Geoblocking",
                        field: "regionalGeoBlocking",
diff --git a/traffic_portal/test/integration/CommonUtils/API.ts 
b/traffic_portal/test/integration/CommonUtils/API.ts
index 8e4375660c..0570f021a0 100644
--- a/traffic_portal/test/integration/CommonUtils/API.ts
+++ b/traffic_portal/test/integration/CommonUtils/API.ts
@@ -296,7 +296,7 @@ export class API {
             const rand = () => Math.floor(Math.random()*255)+1;
             data.ipAddress = `${rand()}.${rand()}.${rand()}.${rand()}`;
         }
-        if(hasProperty(data, 'name')) {
+        if(hasProperty(data, 'name') && !(hasProperty(data, "noRandomize") && 
data.noRandomize === true)) {
             data.name = data.name + randomize;
         }
         if(hasProperty(data, 'requiredCapability')) {
diff --git a/traffic_portal/test/integration/Data/deliveryservices.ts 
b/traffic_portal/test/integration/Data/deliveryservices.ts
index 7bd9c48644..06bc4da2f6 100644
--- a/traffic_portal/test/integration/Data/deliveryservices.ts
+++ b/traffic_portal/test/integration/Data/deliveryservices.ts
@@ -112,6 +112,20 @@ export const deliveryservices = {
                }
        ],
        setup: [
+               {
+                       action: "CreateParameters",
+                       route: "/parameters",
+                       method: "post",
+                       data: [
+                               {
+                                       name: "location",
+                                       value: "/a/b/c/d",
+                                       configFile: "remap.config",
+                                       secure: false,
+                                       noRandomize: true
+                               }
+                       ]
+               },
                {
                        action: "CreateDeliveryServices",
                        route: "/deliveryservices",
@@ -127,6 +141,7 @@ export const deliveryservices = {
                                        initialDispersion: 1,
                                        ipv6RoutingEnabled: true,
                                        logsEnabled: false,
+                                       maxOriginConnections: 4500,
                                        missLat: 41.881944,
                                        missLong: -87.627778,
                                        multiSiteOrigin: false,
@@ -134,6 +149,7 @@ export const deliveryservices = {
                                        protocol: 0,
                                        qstringIgnore: 0,
                                        rangeRequestHandling: 0,
+                                       regional: false,
                                        regionalGeoBlocking: false,
                                        tenantId: 0,
                                        typeId: 1,
diff --git a/traffic_portal/test/integration/Data/jobs.ts 
b/traffic_portal/test/integration/Data/jobs.ts
index 2da6286607..fc52caa598 100644
--- a/traffic_portal/test/integration/Data/jobs.ts
+++ b/traffic_portal/test/integration/Data/jobs.ts
@@ -102,5 +102,5 @@ export const jobs = {
                                }
                        ],
                }
-    ] 
+    ]
 }

Reply via email to