This is an automated email from the ASF dual-hosted git repository.
rob 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 33feb76f10 T3c add parent retry params for first./inner./last. (#6859)
33feb76f10 is described below
commit 33feb76f1040fab09d7893772b95e8a0b010955a
Author: Brian Olsen <[email protected]>
AuthorDate: Thu Jul 28 14:05:31 2022 -0600
T3c add parent retry params for first./inner./last. (#6859)
* Add support for first./inner./last. for parent.config retries
* move merge_parent_groups from mso table into parameters list in another
section
* add documentation for first./inner./last. retry/markdown options
* refactor how parent retry config keys are made
* fix serverPlacement logic for non topology ds, add godoc function comment
* remove extra secondary_mode check and add hasValues check for
IsLastCacheTier
* snidotyaml_test: convert to using ParentConfigRetryKeysDefault for
Algorithm
---
CHANGELOG.md | 1 +
docs/source/admin/quick_howto/multi_site.rst | 44 +-
docs/source/overview/delivery_services.rst | 60 +-
lib/go-atscfg/parentdotconfig.go | 748 ++++++++++++-----------
lib/go-atscfg/parentdotconfig_test.go | 849 +++++++++++++++++++++++++--
lib/go-atscfg/snidotyaml_test.go | 8 +-
lib/go-atscfg/sslservernamedotyaml_test.go | 8 +-
lib/go-atscfg/strategiesdotconfig.go | 7 +-
lib/go-atscfg/strategiesdotconfig_test.go | 755 ++++++++++++++++++++++--
9 files changed, 1992 insertions(+), 488 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ac611ea77..8fec71c9e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,7 @@ The format is based on [Keep a
Changelog](http://keepachangelog.com/en/1.0.0/).
- Change to t3c regex_revalidate so that STALE is no longer explicitly added
for default revalidate rule for ATS version backwards compatibility.
- Change to t3c diff to flag a config file for replacement if owner/group
settings are not `ats`
[#6879](https://github.com/apache/trafficcontrol/issues/6879).
- t3c now looks in the executable dir path for t3c- utilities
+- Added support for parent.config markdown/retry DS parameters using
first./inner./last. prefixes. mso. and <null> prefixes should be deprecated.
### Fixed
- Fixed TO to default route ID to 0, if it is not present in the request
context.
diff --git a/docs/source/admin/quick_howto/multi_site.rst
b/docs/source/admin/quick_howto/multi_site.rst
index 2b648182bf..5e64937ec8 100644
--- a/docs/source/admin/quick_howto/multi_site.rst
+++ b/docs/source/admin/quick_howto/multi_site.rst
@@ -68,33 +68,35 @@ The following steps will take you through the procedure of
setting up an :abbr:`
#) Click :guilabel:`Show profile parameters` to bring up the
:term:`Parameters` screen for the :term:`Profile`. Create the following
:term:`Parameters`:
-
+----------------------------------------+------------------+--------------------------+-------------------------+
- | Parameter Name | Config File Name |
Value | ATS parent.config value |
-
+========================================+==================+==========================+=========================+
- | mso.algorithm | parent.config |
true, false, strict, | round_robin |
- | | |
consistent_hash | |
-
+----------------------------------------+------------------+--------------------------+-------------------------+
- | mso.parent_retry | parent.config |
simple_retry, both, | parent_retry |
- | | |
unavailable_server_retry | |
-
+----------------------------------------+------------------+--------------------------+-------------------------+
- | mso.unavailable_server_retry_responses | parent.config |
list of server response | defaults to the value |
- | | |
codes, eg "500,502,503" | in records.config |
- | | |
| when unused. |
-
+----------------------------------------+------------------+--------------------------+-------------------------+
- | mso.max_simple_retries | parent.config |
Nubmer of retries made | defaults to the value |
- | | |
after a 4xx error | in records.config |
- | | |
| when unused. |
-
+----------------------------------------+------------------+--------------------------+-------------------------+
- | mso.max_unavailable_server_retries | parent.config |
Nubmer of retries made | defaults to the value |
- | | |
after a 5xx error | in records.config |
- | | |
| when unused. |
-
+----------------------------------------+------------------+--------------------------+-------------------------+
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
+ | Parameter Name | Config File Name |
Value | ATS parent.config value |
+
+=========================================+==================+==========================+=========================+
+ | last.algorithm | parent.config |
true, false, strict, | round_robin |
+ | | |
consistent_hash | |
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
+ | last.parent_retry | parent.config |
simple_retry, both, | parent_retry |
+ | | |
unavailable_server_retry | |
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
+ | last.unavailable_server_retry_responses | parent.config |
list of server response | defaults to the value |
+ | | |
codes, eg "500,502,503" | in records.config |
+ | | |
| when unused. |
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
+ | last.max_simple_retries | parent.config |
Nubmer of retries made | defaults to the value |
+ | | |
after a 4xx error | in records.config |
+ | | |
| when unused. |
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
+ | last.max_unavailable_server_retries | parent.config |
Nubmer of retries made | defaults to the value |
+ | | |
after a 5xx error | in records.config |
+ | | |
| when unused. |
+
+-----------------------------------------+------------------+--------------------------+-------------------------+
.. figure:: multi_site/ds_profile_parameters.png
:scale: 100%
:align: center
+ .. deprecated:: ATC 6.2
+
#) In the :term:`Delivery Service` page, select the newly created
``DS_PROFILE`` and save the :term:`Delivery Service`.
#. Turn on parent_proxy_routing in the MID :term:`Profile`.
diff --git a/docs/source/overview/delivery_services.rst
b/docs/source/overview/delivery_services.rst
index 811da8d1b4..d043383f35 100644
--- a/docs/source/overview/delivery_services.rst
+++ b/docs/source/overview/delivery_services.rst
@@ -1003,11 +1003,13 @@ The following :term:`Parameters` must have the
:ref:`Config File <parameter-conf
.. impl-detail:: This :term:`Parameter` does not affect the contents of
``parent.config``, but instead ``strategies.yaml`` in :abbr:`ATS (Apache
Traffic Server)` 9. It has the ``parent.config`` :ref:`parameter-config-file`
value for consistency.
+- ``merge_parent_groups`` - on a Deliver Service :term:`Profile`, if this
exists, moves each of the space-separated :term:`Cache Groups` named in the
:ref:`parameter-value` from the secondary parent list into the primary parent
list. This can be used to combine all parents into a single consistent hash
ring.
+
.. deprecated:: ATCv6.2
In :ref:`to-api` version 4 (unstable at the time of this
writing), TLS versions should be configured using the `TLS Versions`_ property
of the Delivery Service, and support for this :term:`Parameter` will be removed
at some point after the stabilization of :ref:`to-api` version 4.
-Parameters that Affect Multi-Site Origin
-''''''''''''''''''''''''''''''''''''''''
+Parameters that Affect Multi-Site Origin and inside a CDN
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Each :term:`Parameter` directly corresponds to a field in a line of the
:abbr:`ATS (Apache Traffic Server)` `parent.config file
<https://docs.trafficserver.apache.org/en/7.1.x/admin-guide/files/parent.config.en.html>`_
(usually by almost the same name), and documentation for these fields is
provided in the form of links to their entries in the :abbr:`ATS (Apache
Traffic Server)` documentation.
.. _round_robin:
https://docs.trafficserver.apache.org/en/9.1.x/admin-guide/files/parent.config.en.html#parent-config-format-round-robin
@@ -1023,33 +1025,33 @@ Each :term:`Parameter` directly corresponds to a field
in a line of the :abbr:`A
.. table:: :term:`Parameters` of a Delivery Service Profile_ that Affect
:abbr:`MSO (Multi-Site-Origin)` Configuration
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | Name | :abbr:`ATS (Apache
Traffic Server)` `parent.config`_ field | Effect
|
-
+=============================================+============================================================================+=====================================================================================+
- | mso.algorithm | `round_robin`_
| Sets the algorithm used to
determine from which :term:`origin server` content will |
- | |
| be requested.
|
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | mso.max_simple_retries | `max_simple_retries`_
| Sets a strict limit on the
number of "simple retries" allowed before giving up |
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | mso.max_unavailable_server_retries |
`max_unavailable_server_retries`_ |
Sets a strict limit on the number of times the :term:`cache server` will
attempt to |
- | |
| request content from an
:term:`origin server` that has previously been considered |
- | |
| "unavailable".
|
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | mso.parent_retry | `parent_retry`_
| Sets whether the
:term:`cache servers` will use "simple retries", |
- | |
| "unavailable server
retries", or both. |
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | mso.simple_retry_response_codes | **UNKNOWN**
| **UNKNOWN** - supposedly
defines HTTP response codes from an :term:`origin server` |
- | |
| that necessitate a "simple
retry". |
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | mso.unavailable_server_retry_response_codes |
`unavailable_server_retry_responses`_ |
Defines HTTP response codes from an :term:`origin server` that indicate it is
|
- | |
| currently "unavailable".
|
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
- | merge_parent_groups | `parent`_ and
`secondary_parent`_ | Moves each of
the space-separated :term:`Cache Groups` named in the |
- | |
| :ref:`parameter-value`
from the secondary parent list into the primary parent list. |
- | |
| This can be used to
combine all parents into a single consistent hash ring. |
-
+---------------------------------------------+----------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
-
-.. warning:: The ``mso.simple_retry_response_codes`` :term:`Parameter` has no
apparent, possible use according to the :abbr:`ATS (Apache Traffic Server)`
`parent.config documentation
<https://docs.trafficserver.apache.org/en/9.1.x/admin-guide/files/parent.config.en.html>`_.
Whether or not it has any effect - let alone the *intended* effect - is not
known, and its use is therefore strongly discouraged.
+
+---------------------------------------------+--------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | Name | :abbr:`ATS (Apache Traffic
Server)` `parent.config`_ field | Effect
|
+
+=========================================+============================================================+=====================================================================================+
+ | algorithm | `round_robin`_
| Sets the algorithm used to determine from
which :term:`origin server` content will |
+ | |
| be requested.
|
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | max_simple_retries | `max_simple_retries`_
| Sets a strict limit on the number of "simple
retries" allowed before giving up |
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | max_unavailable_server_retries |
`max_unavailable_server_retries`_ | Sets a strict
limit on the number of times the :term:`cache server` will attempt to |
+ | |
| request content from an :term:`origin server`
that has previously been considered |
+ | |
| "unavailable".
|
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | parent_retry | `parent_retry`_
| Sets whether the :term:`cache servers` will
use "simple retries", |
+ | |
| "unavailable server retries", or both.
|
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | simple_retry_response_codes | **UNKNOWN**
| **UNKNOWN** - supposedly defines HTTP response
codes from an :term:`origin server` |
+ | |
| that necessitate a "simple retry".
|
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+ | unavailable_server_retry_response_codes |
`unavailable_server_retry_responses`_ | Defines HTTP
response codes from an :term:`origin server` that indicate it is |
+ | |
| currently "unavailable".
|
+
+-----------------------------------------+------------------------------------------------------------+-------------------------------------------------------------------------------------+
+
+The above :term:`Parameters` are supported for ``first``, ``inner`` and
``last`` tiers by specifying prefixes ``first.``, ``inner.`` and ``last.``,
applicable to both topology and non topology. This allows fine tuning of
markdown and retry behavior inside a CDN.
+
+.. deprecated:: The ``mso.`` prefix is deprecated. ``last.`` prefix should be
preferred although no prefix can also be used.
+
+.. warning:: The `simple_retry_response_codes`` :term:`Parameter` has no
apparent, possible use according to the :abbr:`ATS (Apache Traffic Server)`
`parent.config documentation
<https://docs.trafficserver.apache.org/en/9.1.x/admin-guide/files/parent.config.en.html>`_.
Whether or not it has any effect - let alone the *intended* effect - is not
known, and its use is therefore strongly discouraged.
.. seealso:: To see how the :ref:`Values <parameter-value>` of these
Parameters are interpreted, refer to the `Apache Traffic Server documentation
on the parent.config configuration file
<https://docs.trafficserver.apache.org/en/7.1.x/admin-guide/files/parent.config.en.html>`_
diff --git a/lib/go-atscfg/parentdotconfig.go b/lib/go-atscfg/parentdotconfig.go
index b57a920720..c23c72382c 100644
--- a/lib/go-atscfg/parentdotconfig.go
+++ b/lib/go-atscfg/parentdotconfig.go
@@ -39,20 +39,7 @@ const LineCommentParentDotConfig = LineCommentHash
const ParentConfigFileName = "parent.config"
const ParentConfigParamQStringHandling = "psel.qstring_handling"
-const ParentConfigParamMSOAlgorithm = "mso.algorithm"
-const ParentConfigParamMSOParentRetry = "mso.parent_retry"
-const ParentConfigParamMSOUnavailableServerRetryResponses =
"mso.unavailable_server_retry_responses"
-const ParentConfigParamMSOMaxSimpleRetries = "mso.max_simple_retries"
-const ParentConfigParamMSOMaxUnavailableServerRetries =
"mso.max_unavailable_server_retries"
const ParentConfigParamMergeGroups = "merge_parent_groups"
-const ParentConfigParamAlgorithm = "algorithm"
-const ParentConfigParamQString = "qstring"
-const ParentConfigParamSecondaryMode = "try_all_primaries_before_secondary"
-
-const ParentConfigParamParentRetry = "parent_retry"
-const ParentConfigParamUnavailableServerRetryResponses =
"unavailable_server_retry_responses"
-const ParentConfigParamMaxSimpleRetries = "max_simple_retries"
-const ParentConfigParamMaxUnavailableServerRetries =
"max_unavailable_server_retries"
const ParentConfigDSParamDefaultMSOAlgorithm =
ParentAbstractionServiceRetryPolicyConsistentHash
const ParentConfigDSParamDefaultMSOParentRetry = "both"
@@ -67,6 +54,38 @@ const ParentConfigCacheParamRank = "rank"
const ParentConfigCacheParamNotAParent = "not_a_parent"
const StrategyConfigUsePeering = "use_peering"
+// same across DS
+const ParentConfigParamQString = "qstring"
+
+type ParentConfigRetryKeys struct {
+ Algorithm string
+ SecondaryMode string
+ ParentRetry string
+ MaxSimpleRetries string
+ SimpleRetryResponses string
+ MaxUnavailableRetries string
+ UnavailableRetryResponses string
+}
+
+func MakeParentConfigRetryKeysWithPrefix(prefix string) ParentConfigRetryKeys {
+ return ParentConfigRetryKeys{
+ Algorithm: prefix + "algorithm",
+ SecondaryMode: prefix +
"try_all_primaries_before_secondary",
+ ParentRetry: prefix + "parent_retry",
+ MaxSimpleRetries: prefix + "max_simple_retries",
+ SimpleRetryResponses: prefix +
"simple_server_retry_responses",
+ MaxUnavailableRetries: prefix +
"max_unavailable_server_retries",
+ UnavailableRetryResponses: prefix +
"unavailable_server_retry_responses",
+ }
+}
+
+var ParentConfigRetryKeysFirst = MakeParentConfigRetryKeysWithPrefix("first.")
+var ParentConfigRetryKeysInner = MakeParentConfigRetryKeysWithPrefix("inner.")
+var ParentConfigRetryKeysLast = MakeParentConfigRetryKeysWithPrefix("last.")
+
+var ParentConfigRetryKeysMSO = MakeParentConfigRetryKeysWithPrefix("mso.")
+var ParentConfigRetryKeysDefault = MakeParentConfigRetryKeysWithPrefix("")
+
type OriginHost string
type OriginFQDN string
@@ -331,6 +350,7 @@ func makeParentDotConfigData(
warnings = append(warnings, dsOriginWarns...)
for _, ds := range dses {
+
if ds.XMLID == nil || *ds.XMLID == "" {
warnings = append(warnings, "got ds with missing XMLID,
skipping!")
continue
@@ -357,14 +377,11 @@ func makeParentDotConfigData(
continue
}
- // Note these Parameters are only used for MSO for legacy
DeliveryServiceServers DeliveryServices (except QueryStringHandling which is
used by all DeliveryServices).
- // Topology DSes use them for all DSes, MSO and non-MSO.
- dsParams, dsParamsWarnings := getParentDSParams(ds,
profileParentConfigParams)
- warnings = append(warnings, dsParamsWarnings...)
+ isMSO := ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin
// TODO put these in separate functions. No if-statement should
be this long.
if ds.Topology != nil && *ds.Topology != "" {
- txt, topoWarnings, err := getTopologyParentConfigLine(
+ pasvc, topoWarnings, err := getTopologyParentConfigLine(
server,
serversWithParams,
&ds,
@@ -374,7 +391,8 @@ func makeParentDotConfigData(
serverCapabilities,
dsRequiredCapabilities,
cacheGroups,
- dsParams,
+ profileParentConfigParams,
+ isMSO,
atsMajorVer,
dsOrigins[DeliveryServiceID(*ds.ID)],
opt.AddComments,
@@ -386,214 +404,231 @@ func makeParentDotConfigData(
continue
}
- if txt != nil { // will be nil with no error if this
server isn't in the Topology, or if it doesn't have the Required Capabilities
- parentAbstraction.Services =
append(parentAbstraction.Services, txt)
- }
- } else if cacheIsTopLevel {
- parentQStr := false
- if dsParams.QueryStringHandling == "" &&
dsParams.Algorithm == tc.AlgorithmConsistentHash && ds.QStringIgnore != nil &&
tc.QStringIgnore(*ds.QStringIgnore) == tc.QStringIgnoreUseInCacheKeyAndPassUp {
- parentQStr = true
+ if pasvc != nil { // will be nil with no error if this
server isn't in the Topology, or if it doesn't have the Required Capabilities
+ parentAbstraction.Services =
append(parentAbstraction.Services, pasvc)
}
-
- orgFQDNStr := *ds.OrgServerFQDN
- // if this cache isn't the last tier, i.e. we're not
going to the origin, use http not https
- if isLastCacheTier :=
noTopologyServerIsLastCacheForDS(server, &ds); !isLastCacheTier {
- orgFQDNStr = strings.Replace(orgFQDNStr,
`https://`, `http://`, -1)
- }
- orgURI, orgWarns, err := getOriginURI(orgFQDNStr)
- warnings = append(warnings, orgWarns...)
- if err != nil {
- warnings = append(warnings, "DS '"+*ds.XMLID+"'
has malformed origin URI: '"+orgFQDNStr+"': skipping!"+err.Error())
- continue
+ } else {
+ isLastCacheTier :=
noTopologyServerIsLastCacheForDS(server, &ds)
+ serverPlacement := TopologyPlacement{
+ IsLastCacheTier: isLastCacheTier,
+ IsFirstCacheTier: !isLastCacheTier ||
!ds.Type.UsesMidCache(),
}
- textLine := &ParentAbstractionService{}
- textLine.Name = *ds.XMLID
+ dsParams, dswarns := getParentDSParams(ds,
profileParentConfigParams, serverPlacement, isMSO)
+ warnings = append(warnings, dswarns...)
- if ds.OriginShield != nil && *ds.OriginShield != "" {
+ if cacheIsTopLevel {
+ parentQStr := false
+ if dsParams.QueryStringHandling == "" &&
dsParams.Algorithm == tc.AlgorithmConsistentHash && ds.QStringIgnore != nil &&
tc.QStringIgnore(*ds.QStringIgnore) == tc.QStringIgnoreUseInCacheKeyAndPassUp {
+ parentQStr = true
+ }
- policy :=
ParentAbstractionServiceRetryPolicyConsistentHash
- if parentSelectAlg :=
serverParams[ParentConfigParamAlgorithm]; strings.TrimSpace(parentSelectAlg) !=
"" {
- paramPolicy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(parentSelectAlg)
- if paramPolicy !=
ParentAbstractionServiceRetryPolicyInvalid {
- policy = paramPolicy
- } else {
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed "+ParentConfigParamAlgorithm+" parameter
'"+parentSelectAlg+"', not using!")
- }
+ orgFQDNStr := *ds.OrgServerFQDN
+ // if this cache isn't the last tier, i.e.
we're not going to the origin, use http not https
+ if !isLastCacheTier {
+ orgFQDNStr =
strings.Replace(orgFQDNStr, `https://`, `http://`, -1)
}
- textLine.Comment =
makeParentComment(opt.AddComments, *ds.XMLID, "")
- textLine.DestDomain = orgURI.Hostname()
- textLine.Port, err = strconv.Atoi(orgURI.Port())
+ orgURI, orgWarns, err :=
getOriginURI(orgFQDNStr)
+ warnings = append(warnings, orgWarns...)
if err != nil {
- if strings.ToLower(orgURI.Scheme) ==
"https" {
- textLine.Port = 443
- } else {
- textLine.Port = 80
- }
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(textLine.Port)+"! : "+err.Error())
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' has malformed origin URI: '"+orgFQDNStr+"':
skipping!"+err.Error())
+ continue
}
- fqdnPort := strings.Split(*ds.OriginShield, ":")
- parent := &ParentAbstractionServiceParent{}
- parent.FQDN = fqdnPort[0]
- if len(fqdnPort) > 1 {
- parent.Port, err =
strconv.Atoi(fqdnPort[1])
+ pasvc := &ParentAbstractionService{}
+ pasvc.Name = *ds.XMLID
+
+ if ds.OriginShield != nil && *ds.OriginShield
!= "" {
+
+ policy :=
ParentAbstractionServiceRetryPolicyConsistentHash
+
+ if parentSelectAlg :=
serverParams[ParentConfigRetryKeysDefault.Algorithm];
strings.TrimSpace(parentSelectAlg) != "" {
+ paramPolicy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(parentSelectAlg)
+ if paramPolicy !=
ParentAbstractionServiceRetryPolicyInvalid {
+ policy = paramPolicy
+ } else {
+ warnings =
append(warnings, "DS '"+*ds.XMLID+"' had malformed
"+ParentConfigRetryKeysDefault.Algorithm+" parameter '"+parentSelectAlg+"', not
using!")
+ }
+ }
+ pasvc.Comment =
makeParentComment(opt.AddComments, *ds.XMLID, "")
+ pasvc.DestDomain = orgURI.Hostname()
+ pasvc.Port, err =
strconv.Atoi(orgURI.Port())
if err != nil {
+ if
strings.ToLower(orgURI.Scheme) == "https" {
+ pasvc.Port = 443
+ } else {
+ pasvc.Port = 80
+ }
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(pasvc.Port)+"! : "+err.Error())
+ }
+
+ fqdnPort :=
strings.Split(*ds.OriginShield, ":")
+ parent :=
&ParentAbstractionServiceParent{}
+ parent.FQDN = fqdnPort[0]
+ if len(fqdnPort) > 1 {
+ parent.Port, err =
strconv.Atoi(fqdnPort[1])
+ if err != nil {
+ parent.Port = 80
+ warnings =
append(warnings, "DS '"+*ds.XMLID+"' had malformed origin port:
'"+*ds.OriginShield+"': using "+strconv.Itoa(parent.Port)+"! : "+err.Error())
+ }
+ } else {
parent.Port = 80
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+*ds.OriginShield+"': using
"+strconv.Itoa(parent.Port)+"! : "+err.Error())
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had no origin port: '"+*ds.OriginShield+"': using
"+strconv.Itoa(parent.Port)+"!")
}
- } else {
- parent.Port = 80
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had no origin port: '"+*ds.OriginShield+"': using
"+strconv.Itoa(parent.Port)+"!")
- }
- textLine.Parents = append(textLine.Parents,
parent)
- textLine.RetryPolicy = policy
- textLine.GoDirect = true
+ pasvc.Parents = append(pasvc.Parents,
parent)
+ pasvc.RetryPolicy = policy
+ pasvc.GoDirect = true
- // textLine += "dest_domain=" +
orgURI.Hostname() + " port=" + orgURI.Port() + " parent=" + *ds.OriginShield +
" " + algorithm + " go_direct=true\n"
+ // textLine += "dest_domain=" +
orgURI.Hostname() + " port=" + orgURI.Port() + " parent=" + *ds.OriginShield +
" " + algorithm + " go_direct=true\n"
- } else if ds.MultiSiteOrigin != nil &&
*ds.MultiSiteOrigin {
- textLine.Comment =
makeParentComment(opt.AddComments, *ds.XMLID, "")
- textLine.DestDomain = orgURI.Hostname()
- textLine.Port, err = strconv.Atoi(orgURI.Port())
- if err != nil {
- textLine.Port = 80
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(textLine.Port)+"! : "+err.Error())
- }
+ } else if ds.MultiSiteOrigin != nil &&
*ds.MultiSiteOrigin {
+ pasvc.Comment =
makeParentComment(opt.AddComments, *ds.XMLID, "")
+ pasvc.DestDomain = orgURI.Hostname()
+ pasvc.Port, err =
strconv.Atoi(orgURI.Port())
+ if err != nil {
+ pasvc.Port = 80
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(pasvc.Port)+"! : "+err.Error())
+ }
- // textLine += "dest_domain=" +
orgURI.Hostname() + " port=" + orgURI.Port() + " "
- if len(parentInfos) == 0 {
- }
+ // textLine += "dest_domain=" +
orgURI.Hostname() + " port=" + orgURI.Port() + " "
+ if len(parentInfos) == 0 {
+ }
- if
len(parentInfos[OriginHost(orgURI.Hostname())]) == 0 {
- // TODO error? emulates Perl
- warnings = append(warnings, "DS
"+*ds.XMLID+" has no parent servers")
- }
+ if
len(parentInfos[OriginHost(orgURI.Hostname())]) == 0 {
+ // TODO error? emulates Perl
+ warnings = append(warnings, "DS
"+*ds.XMLID+" has no parent servers")
+ }
- parents, secondaryParents, secondaryMode,
parentWarns := getMSOParentStrs(&ds,
parentInfos[OriginHost(orgURI.Hostname())], atsMajorVer, dsParams.Algorithm,
dsParams.TryAllPrimariesBeforeSecondary)
- warnings = append(warnings, parentWarns...)
- textLine.Parents = parents
- textLine.SecondaryParents = secondaryParents
- textLine.SecondaryMode = secondaryMode
- textLine.RetryPolicy = dsParams.Algorithm //
TODO convert
- textLine.IgnoreQueryStringInParentSelection =
!parentQStr
- textLine.GoDirect = true
-
- // textLine += parents + secondaryParents + `
round_robin=` + dsParams.Algorithm + ` qstring=` + parentQStr + `
go_direct=false parent_is_proxy=false`
- prWarns := []string{}
- textLine.MaxSimpleRetries,
textLine.MaxMarkdownRetries, textLine.MarkdownResponseCodes,
textLine.ErrorResponseCodes, prWarns = getParentRetryStr(true, atsMajorVer,
dsParams.ParentRetry, dsParams.UnavailableServerRetryResponses,
dsParams.MaxSimpleRetries, dsParams.MaxUnavailableServerRetries)
- warnings = append(warnings, prWarns...)
+ parents, secondaryParents,
secondaryMode, parentWarns := getMSOParentStrs(&ds,
parentInfos[OriginHost(orgURI.Hostname())], atsMajorVer, dsParams.Algorithm,
dsParams.TryAllPrimariesBeforeSecondary)
+ warnings = append(warnings,
parentWarns...)
+ pasvc.Parents = parents
+ pasvc.SecondaryParents =
secondaryParents
+ pasvc.SecondaryMode = secondaryMode
+ pasvc.RetryPolicy = dsParams.Algorithm
// TODO convert
+
pasvc.IgnoreQueryStringInParentSelection = !parentQStr
+ pasvc.GoDirect = true
- parentAbstraction.Services =
append(parentAbstraction.Services, textLine)
- }
- } else {
- queryStringHandling :=
ParentSelectParamQStringHandlingToBool(serverParams[ParentConfigParamQStringHandling])
// "qsh" in Perl
- if queryStringHandling == nil &&
serverParams[ParentConfigParamQStringHandling] != "" {
- warnings = append(warnings, "Server Parameter
'"+ParentConfigParamQStringHandling+"' value
'"+serverParams[ParentConfigParamQStringHandling]+"' malformed, not using!")
- }
+ // textLine += parents +
secondaryParents + ` round_robin=` + dsParams.Algorithm + ` qstring=` +
parentQStr + ` go_direct=false parent_is_proxy=false`
- roundRobin :=
ParentAbstractionServiceRetryPolicyConsistentHash
- // roundRobin := `round_robin=consistent_hash`
- goDirect := false
- // goDirect := `go_direct=false`
+ prWarns :=
dsParams.FillParentSvcRetries(cacheIsTopLevel, atsMajorVer, pasvc)
+ warnings = append(warnings, prWarns...)
- parents, secondaryParents, secondaryMode, parentWarns
:= getParentStrs(&ds, dsRequiredCapabilities,
parentInfos[deliveryServicesAllParentsKey], atsMajorVer,
dsParams.TryAllPrimariesBeforeSecondary)
- warnings = append(warnings, parentWarns...)
+ parentAbstraction.Services =
append(parentAbstraction.Services, pasvc)
+ }
+ } else {
+ queryStringHandling :=
ParentSelectParamQStringHandlingToBool(serverParams[ParentConfigParamQStringHandling])
// "qsh" in Perl
+ if queryStringHandling == nil &&
serverParams[ParentConfigParamQStringHandling] != "" {
+ warnings = append(warnings, "Server
Parameter '"+ParentConfigParamQStringHandling+"' value
'"+serverParams[ParentConfigParamQStringHandling]+"' malformed, not using!")
+ }
- text := &ParentAbstractionService{}
- text.Name = *ds.XMLID
+ roundRobin :=
ParentAbstractionServiceRetryPolicyConsistentHash
+ // roundRobin := `round_robin=consistent_hash`
+ goDirect := false
+ // goDirect := `go_direct=false`
- // peering ring check
- if dsParams.UsePeering {
- secondaryMode =
ParentAbstractionServiceParentSecondaryModePeering
- }
+ parents, secondaryParents, secondaryMode,
parentWarns := getParentStrs(&ds, dsRequiredCapabilities,
parentInfos[deliveryServicesAllParentsKey], atsMajorVer,
dsParams.TryAllPrimariesBeforeSecondary)
+ warnings = append(warnings, parentWarns...)
- orgFQDNStr := *ds.OrgServerFQDN
- // if this cache isn't the last tier, i.e. we're not
going to the origin, use http not https
- if isLastCacheTier :=
noTopologyServerIsLastCacheForDS(server, &ds); !isLastCacheTier {
- orgFQDNStr = strings.Replace(orgFQDNStr,
`https://`, `http://`, -1)
- }
- orgURI, orgWarns, err := getOriginURI(orgFQDNStr)
- warnings = append(warnings, orgWarns...)
- if err != nil {
- warnings = append(warnings, "DS '"+*ds.XMLID+"'
had malformed origin URI: '"+*ds.OrgServerFQDN+"': skipping!"+err.Error())
- continue
- }
+ pasvc := &ParentAbstractionService{}
+ pasvc.Name = *ds.XMLID
- text.Comment = makeParentComment(opt.AddComments,
*ds.XMLID, "")
+ // peering ring check
+ if dsParams.UsePeering {
+ secondaryMode =
ParentAbstractionServiceParentSecondaryModePeering
+ }
- // TODO encode this in a DSType func, IsGoDirect() ?
- if *ds.Type == tc.DSTypeHTTPNoCache || *ds.Type ==
tc.DSTypeHTTPLive || *ds.Type == tc.DSTypeDNSLive {
- text.DestDomain = orgURI.Hostname()
- text.Port, err = strconv.Atoi(orgURI.Port())
+ orgFQDNStr := *ds.OrgServerFQDN
+ // if this cache isn't the last tier, i.e.
we're not going to the origin, use http not https
+ if !isLastCacheTier {
+ orgFQDNStr =
strings.Replace(orgFQDNStr, `https://`, `http://`, -1)
+ }
+ orgURI, orgWarns, err :=
getOriginURI(orgFQDNStr)
+ warnings = append(warnings, orgWarns...)
if err != nil {
- if strings.ToLower(orgURI.Scheme) ==
"https" {
- text.Port = 443
- } else {
- text.Port = 80
- }
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(text.Port)+"! : "+err.Error())
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin URI: '"+*ds.OrgServerFQDN+"':
skipping!"+err.Error())
+ continue
}
- text.GoDirect = true
-
- text.Parents =
[]*ParentAbstractionServiceParent{&ParentAbstractionServiceParent{
- FQDN: text.DestDomain,
- Port: text.Port,
- Weight: 1.0,
- }}
- // text += `dest_domain=` + orgURI.Hostname() +
` port=` + orgURI.Port() + ` go_direct=true` + "\n"
+ pasvc.Comment =
makeParentComment(opt.AddComments, *ds.XMLID, "")
- } else {
- // check for profile psel.qstring_handling. If
this parameter is assigned to the server profile,
- // then edges will use the qstring handling
value specified in the parameter for all profiles.
-
- // If there is no defined parameter in the
profile, then check the delivery service profile.
- // If psel.qstring_handling exists in the DS
profile, then we use that value for the specified DS only.
- // This is used only if not overridden by a
server profile qstring handling parameter.
-
- // TODO refactor this logic, hard to understand
(transliterated from Perl)
- dsQSH := queryStringHandling
- if dsQSH == nil {
- dsQSH =
ParentSelectParamQStringHandlingToBool(dsParams.QueryStringHandling)
- if dsQSH == nil &&
dsParams.QueryStringHandling != "" {
- warnings = append(warnings,
"Delivery Service parameter '"+ParentConfigParamQStringHandling+"' value
'"+dsParams.QueryStringHandling+"' malformed, not using!")
+ // TODO encode this in a DSType func,
IsGoDirect() ?
+ if *ds.Type == tc.DSTypeHTTPNoCache || *ds.Type
== tc.DSTypeHTTPLive || *ds.Type == tc.DSTypeDNSLive {
+ pasvc.DestDomain = orgURI.Hostname()
+ pasvc.Port, err =
strconv.Atoi(orgURI.Port())
+ if err != nil {
+ if
strings.ToLower(orgURI.Scheme) == "https" {
+ pasvc.Port = 443
+ } else {
+ pasvc.Port = 80
+ }
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(pasvc.Port)+"! : "+err.Error())
}
- }
- parentQStr := dsQSH
- if parentQStr == nil {
- v := false
- parentQStr = &v
- }
- if ds.QStringIgnore != nil &&
tc.QStringIgnore(*ds.QStringIgnore) == tc.QStringIgnoreUseInCacheKeyAndPassUp
&& dsQSH == nil {
- v := true
- parentQStr = &v
- }
- if parentQStr == nil {
- b :=
!DefaultIgnoreQueryStringInParentSelection
- parentQStr = &b
- }
+ pasvc.GoDirect = true
- text.DestDomain = orgURI.Hostname()
- text.Port, err = strconv.Atoi(orgURI.Port())
- if err != nil {
- if strings.ToLower(orgURI.Scheme) ==
"https" {
- text.Port = 443
- } else {
- text.Port = 80
+ pasvc.Parents =
[]*ParentAbstractionServiceParent{&ParentAbstractionServiceParent{
+ FQDN: pasvc.DestDomain,
+ Port: pasvc.Port,
+ Weight: 1.0,
+ }}
+
+ // text += `dest_domain=` +
orgURI.Hostname() + ` port=` + orgURI.Port() + ` go_direct=true` + "\n"
+ } else {
+
+ // check for profile
psel.qstring_handling. If this parameter is assigned to the server profile,
+ // then edges will use the qstring
handling value specified in the parameter for all profiles.
+
+ // If there is no defined parameter in
the profile, then check the delivery service profile.
+ // If psel.qstring_handling exists in
the DS profile, then we use that value for the specified DS only.
+ // This is used only if not overridden
by a server profile qstring handling parameter.
+
+ // TODO refactor this logic, hard to
understand (transliterated from Perl)
+ dsQSH := queryStringHandling
+ if dsQSH == nil {
+ dsQSH =
ParentSelectParamQStringHandlingToBool(dsParams.QueryStringHandling)
+ if dsQSH == nil &&
dsParams.QueryStringHandling != "" {
+ warnings =
append(warnings, "Delivery Service parameter
'"+ParentConfigParamQStringHandling+"' value '"+dsParams.QueryStringHandling+"'
malformed, not using!")
+ }
+
+ }
+ parentQStr := dsQSH
+ if parentQStr == nil {
+ v := false
+ parentQStr = &v
+ }
+ if ds.QStringIgnore != nil &&
tc.QStringIgnore(*ds.QStringIgnore) == tc.QStringIgnoreUseInCacheKeyAndPassUp
&& dsQSH == nil {
+ v := true
+ parentQStr = &v
+ }
+ if parentQStr == nil {
+ b :=
!DefaultIgnoreQueryStringInParentSelection
+ parentQStr = &b
}
- warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(text.Port)+"! : "+err.Error())
+
+ pasvc.DestDomain = orgURI.Hostname()
+ pasvc.Port, err =
strconv.Atoi(orgURI.Port())
+ if err != nil {
+ if
strings.ToLower(orgURI.Scheme) == "https" {
+ pasvc.Port = 443
+ } else {
+ pasvc.Port = 80
+ }
+ warnings = append(warnings, "DS
'"+*ds.XMLID+"' had malformed origin port: '"+orgURI.Port()+"': using
"+strconv.Itoa(pasvc.Port)+"! : "+err.Error())
+ }
+ pasvc.Parents = parents
+ pasvc.SecondaryParents =
secondaryParents
+ pasvc.SecondaryMode = secondaryMode
+ pasvc.RetryPolicy = roundRobin
+ pasvc.GoDirect = goDirect
+
pasvc.IgnoreQueryStringInParentSelection = !*parentQStr
+ // text += `dest_domain=` +
orgURI.Hostname() + ` port=` + orgURI.Port() + ` ` + parents + ` ` +
secondaryParents + ` ` + roundRobin + ` ` + goDirect + ` qstring=` + parentQStr
+ "\n"
}
- text.Parents = parents
- text.SecondaryParents = secondaryParents
- text.SecondaryMode = secondaryMode
- text.RetryPolicy = roundRobin
- text.GoDirect = goDirect
- text.IgnoreQueryStringInParentSelection =
!*parentQStr
- // text += `dest_domain=` + orgURI.Hostname() +
` port=` + orgURI.Port() + ` ` + parents + ` ` + secondaryParents + ` ` +
roundRobin + ` ` + goDirect + ` qstring=` + parentQStr + "\n"
+
+ prWarns :=
dsParams.FillParentSvcRetries(cacheIsTopLevel, atsMajorVer, pasvc)
+ warnings = append(warnings, prWarns...)
+
+ parentAbstraction.Services =
append(parentAbstraction.Services, pasvc)
}
- parentAbstraction.Services =
append(parentAbstraction.Services, text)
}
}
@@ -612,7 +647,8 @@ func makeParentDotConfigData(
defaultDestText.DestDomain = `.`
defaultDestText.Parents = parents
// defaultDestText = `dest_domain=. ` + parents
- if serverParams[ParentConfigParamAlgorithm] ==
tc.AlgorithmConsistentHash {
+
+ if serverParams[ParentConfigRetryKeysDefault.Algorithm] ==
tc.AlgorithmConsistentHash {
defaultDestText.SecondaryParents = secondaryParents
defaultDestText.SecondaryMode = secondaryMode
// defaultDestText += secondaryParents
@@ -802,32 +838,101 @@ type originURI struct {
const deliveryServicesAllParentsKey = "all_parents"
type parentDSParams struct {
- Algorithm ParentAbstractionServiceRetryPolicy
+ Algorithm ParentAbstractionServiceRetryPolicy
+ QueryStringHandling string
+
+ HasRetryParams bool
ParentRetry string
- UnavailableServerRetryResponses string
MaxSimpleRetries string
MaxUnavailableServerRetries string
- QueryStringHandling string
+ SimpleServerRetryResponses string
+ UnavailableServerRetryResponses string
TryAllPrimariesBeforeSecondary bool
- UsePeering bool
- MergeGroups []string
+
+ UsePeering bool
+ MergeGroups []string
+}
+
+// FillParentRetries populates the parentDSParams retries values from the ds
parameters map for given ds parameter keys.
+// Returns if any params found and any warnings.
+func (dsp *parentDSParams) FillParentRetries(keys ParentConfigRetryKeys,
dsParams map[string]string, dsid string) (bool, []string) {
+ var warnings []string
+ hasValues := false
+
+ if v, ok := dsParams[keys.Algorithm]; ok && strings.TrimSpace(v) != "" {
+ policy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(v)
+ if policy != ParentAbstractionServiceRetryPolicyInvalid {
+ dsp.Algorithm = policy
+ hasValues = true
+ } else {
+ warnings = append(warnings, "DS '"+dsid+"' had
malformed "+keys.Algorithm+" parameter '"+v+"', not using!")
+ }
+ }
+
+ if v, ok := dsParams[keys.ParentRetry]; ok {
+ dsp.ParentRetry = v
+ hasValues = true
+ }
+
+ if v, ok := dsParams[keys.MaxSimpleRetries]; ok {
+ dsp.MaxSimpleRetries = v
+ hasValues = true
+ }
+ if v, ok := dsParams[keys.MaxUnavailableRetries]; ok {
+ dsp.MaxUnavailableServerRetries = v
+ hasValues = true
+ }
+
+ if v, ok := dsParams[keys.SimpleRetryResponses]; ok {
+ if unavailableServerRetryResponsesValid(v) {
+ dsp.SimpleServerRetryResponses = v
+ hasValues = true
+ } else {
+ warnings = append(warnings, "DS '"+dsid+"' had
malformed "+keys.SimpleRetryResponses+" parameter '"+v+"', not using!")
+ }
+ }
+
+ if v, ok := dsParams[keys.UnavailableRetryResponses]; ok {
+ if unavailableServerRetryResponsesValid(v) {
+ dsp.UnavailableServerRetryResponses = v
+ hasValues = true
+ } else {
+ warnings = append(warnings, "DS '"+dsid+"' had
malformed "+keys.UnavailableRetryResponses+" parameter '"+v+"', not using!")
+ }
+ }
+
+ if v, ok := dsParams[keys.SecondaryMode]; ok {
+ if v == "false" {
+ dsp.TryAllPrimariesBeforeSecondary = false
+ } else {
+ dsp.TryAllPrimariesBeforeSecondary = true
+ if v != "" {
+ warnings = append(warnings, "DS '"+dsid+"' had
Parameter "+keys.SecondaryMode+" which is used if it exists, the value is
ignored (unless false) ! Non-empty value '"+v+"' will be ignored!")
+ }
+ }
+ }
+
+ return hasValues, warnings
}
// getDSParams returns the Delivery Service Profile Parameters used in
parent.config, and any warnings.
// If Parameters don't exist, defaults are returned. Non-MSO Delivery Services
default to no custom retry logic (we should reevaluate that).
// Note these Parameters are only used for MSO for legacy
DeliveryServiceServers DeliveryServices.
// Topology DSes use them for all DSes, MSO and non-MSO.
-func getParentDSParams(ds DeliveryService, profileParentConfigParams
map[string]map[string]string) (parentDSParams, []string) {
+func getParentDSParams(ds DeliveryService, profileParentConfigParams
map[string]map[string]string, serverPlacement TopologyPlacement, isMSO bool)
(parentDSParams, []string) {
warnings := []string{}
params := parentDSParams{}
- isMSO := ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin
- if isMSO {
+
+ // Default values for origin facing MSO tier
+ if serverPlacement.IsLastCacheTier && isMSO {
params.Algorithm = ParentConfigDSParamDefaultMSOAlgorithm
params.ParentRetry = ParentConfigDSParamDefaultMSOParentRetry
params.UnavailableServerRetryResponses =
ParentConfigDSParamDefaultMSOUnavailableServerRetryResponses
params.MaxSimpleRetries =
strconv.Itoa(ParentConfigDSParamDefaultMaxSimpleRetries)
params.MaxUnavailableServerRetries =
strconv.Itoa(ParentConfigDSParamDefaultMaxUnavailableServerRetries)
+ params.HasRetryParams = true
}
+
if ds.ProfileName == nil || *ds.ProfileName == "" {
return params, warnings
}
@@ -840,68 +945,42 @@ func getParentDSParams(ds DeliveryService,
profileParentConfigParams map[string]
params.UsePeering = true
}
}
+
// the following may be blank, no default
params.QueryStringHandling = dsParams[ParentConfigParamQStringHandling]
params.MergeGroups =
strings.Split(dsParams[ParentConfigParamMergeGroups], " ")
- // TODO deprecate & remove "mso." Parameters - there was never a reason
to restrict these settings to MSO.
- if isMSO {
- if v, ok := dsParams[ParentConfigParamMSOAlgorithm]; ok &&
strings.TrimSpace(v) != "" {
- policy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(v)
- if policy != ParentAbstractionServiceRetryPolicyInvalid
{
- params.Algorithm = policy
- } else {
- warnings = append(warnings, "DS '"+*ds.XMLID+"'
had malformed "+ParentConfigParamMSOAlgorithm+" parameter '"+v+"', not using!")
- }
- }
- if v, ok := dsParams[ParentConfigParamMSOParentRetry]; ok {
- params.ParentRetry = v
- }
- if v, ok :=
dsParams[ParentConfigParamMSOUnavailableServerRetryResponses]; ok {
- if v != "" && !unavailableServerRetryResponsesValid(v) {
- warnings = append(warnings, "DS '"+*ds.XMLID+"'
had malformed "+ParentConfigParamMSOUnavailableServerRetryResponses+" parameter
'"+v+"', not using!")
- } else if v != "" {
- params.UnavailableServerRetryResponses = v
- }
+ // progressively fill in the params
+ if serverPlacement.IsLastCacheTier {
+ // mso. prefix lowest priority
+ if isMSO {
+ hasVals, warns :=
params.FillParentRetries(ParentConfigRetryKeysMSO, dsParams, *ds.XMLID)
+ params.HasRetryParams = params.HasRetryParams || hasVals
+ warnings = append(warnings, warns...)
}
- if v, ok := dsParams[ParentConfigParamMSOMaxSimpleRetries]; ok {
- params.MaxSimpleRetries = v
- }
- if v, ok :=
dsParams[ParentConfigParamMSOMaxUnavailableServerRetries]; ok {
- params.MaxUnavailableServerRetries = v
- }
- }
- // Even if the DS is MSO, non-"mso." Parameters override "mso." ones,
because they're newer.
- if v, ok := dsParams[ParentConfigParamAlgorithm]; ok &&
strings.TrimSpace(v) != "" {
- policy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(v)
- if policy != ParentAbstractionServiceRetryPolicyInvalid {
- params.Algorithm = policy
- } else {
- warnings = append(warnings, "DS '"+*ds.XMLID+"' had
malformed "+ParentConfigParamAlgorithm+" parameter '"+v+"', not using!")
- }
- }
- if v, ok := dsParams[ParentConfigParamParentRetry]; ok {
- params.ParentRetry = v
- }
- if v, ok := dsParams[ParentConfigParamUnavailableServerRetryResponses];
ok {
- if v != "" && !unavailableServerRetryResponsesValid(v) {
- warnings = append(warnings, "DS '"+*ds.XMLID+"' had
malformed "+ParentConfigParamUnavailableServerRetryResponses+" parameter
'"+v+"', not using!")
- } else if v != "" {
- params.UnavailableServerRetryResponses = v
- }
- }
- if v, ok := dsParams[ParentConfigParamMaxSimpleRetries]; ok {
- params.MaxSimpleRetries = v
- }
- if v, ok := dsParams[ParentConfigParamMaxUnavailableServerRetries]; ok {
- params.MaxUnavailableServerRetries = v
- }
- if v, ok := dsParams[ParentConfigParamSecondaryMode]; ok {
- if v != "" {
- warnings = append(warnings, "DS '"+*ds.XMLID+"' had
Parameter "+ParentConfigParamSecondaryMode+" which is used if it exists, the
value is ignored! Non-empty value '"+v+"' will be ignored!")
- }
- params.TryAllPrimariesBeforeSecondary = true
+ // no prefix next priority
+ hasVals, warns :=
params.FillParentRetries(ParentConfigRetryKeysDefault, dsParams, *ds.XMLID)
+ warnings = append(warnings, warns...)
+ params.HasRetryParams = params.HasRetryParams || hasVals
+
+ // last. prefix highest priority
+ hasVals, warns =
params.FillParentRetries(ParentConfigRetryKeysLast, dsParams, *ds.XMLID)
+ warnings = append(warnings, warns...)
+ params.HasRetryParams = params.HasRetryParams || hasVals
+
+ } else if serverPlacement.IsInnerCacheTier {
+ hasVals, warns :=
params.FillParentRetries(ParentConfigRetryKeysInner, dsParams, *ds.XMLID)
+ warnings = append(warnings, warns...)
+
+ // Normal inner behavior has no parent retry strings
+ params.HasRetryParams = hasVals
+ } else { // if serverPlacement.IsFirstCacheTier {
+ hasVals, warns :=
params.FillParentRetries(ParentConfigRetryKeysFirst, dsParams, *ds.XMLID)
+ warnings = append(warnings, warns...)
+
+ // Normal first behavior has no parent retry strings
+ params.HasRetryParams = hasVals
}
return params, warnings
@@ -919,7 +998,8 @@ func getTopologyParentConfigLine(
serverCapabilities map[int]map[ServerCapability]struct{},
dsRequiredCapabilities map[int]map[ServerCapability]struct{},
cacheGroups map[tc.CacheGroupName]tc.CacheGroupNullable,
- dsParams parentDSParams,
+ profileParentConfigParams map[string]map[string]string,
+ isMSO bool,
atsMajorVer int,
dsOrigins map[ServerID]struct{},
addComments bool,
@@ -935,14 +1015,17 @@ func getTopologyParentConfigLine(
}
serverPlacement, err :=
getTopologyPlacement(tc.CacheGroupName(*server.Cachegroup), topology,
cacheGroups, ds)
-
if err != nil {
return nil, warnings, errors.New("getting topology placement: "
+ err.Error())
}
+
if !serverPlacement.InTopology {
return nil, warnings, nil // server isn't in topology, no error
}
+ dsParams, dswarns := getParentDSParams(*ds, profileParentConfigParams,
serverPlacement, isMSO)
+ warnings = append(warnings, dswarns...)
+
orgFQDNStr := *ds.OrgServerFQDN
// if this cache isn't the last tier, i.e. we're not going to the
origin, use http not https
if !serverPlacement.IsLastCacheTier {
@@ -954,11 +1037,11 @@ func getTopologyParentConfigLine(
return nil, warnings, errors.New("DS '" + *ds.XMLID + "' has
malformed origin URI: '" + *ds.OrgServerFQDN + "': skipping!" + err.Error())
}
- txt := &ParentAbstractionService{}
- txt.Name = *ds.XMLID
- txt.Comment = makeParentComment(addComments, *ds.XMLID, *ds.Topology)
- txt.DestDomain = orgURI.Hostname()
- txt.Port, err = strconv.Atoi(orgURI.Port())
+ pasvc := &ParentAbstractionService{}
+ pasvc.Name = *ds.XMLID
+ pasvc.Comment = makeParentComment(addComments, *ds.XMLID, *ds.Topology)
+ pasvc.DestDomain = orgURI.Hostname()
+ pasvc.Port, err = strconv.Atoi(orgURI.Port())
if err != nil {
return nil, warnings, fmt.Errorf("parent %v port '%v' was not
an integer", orgURI, orgURI.Port())
}
@@ -966,6 +1049,7 @@ func getTopologyParentConfigLine(
parents, secondaryParents, parentWarnings, err :=
getTopologyParents(server, ds, serversWithParams, parentConfigParams, topology,
serverPlacement.IsLastTier, serverCapabilities, dsRequiredCapabilities,
dsOrigins, dsParams.MergeGroups)
warnings = append(warnings, parentWarnings...)
+
if err != nil {
return nil, warnings, errors.New("getting topology parents for
'" + *ds.XMLID + "': skipping! " + err.Error())
}
@@ -979,22 +1063,22 @@ func getTopologyParentConfigLine(
}
}
- txt.Parents = parents
+ pasvc.Parents = parents
// txt += ` parent="` + strings.Join(parents, `;`) + `"`
if len(secondaryParents) > 0 {
- txt.SecondaryParents = secondaryParents
+ pasvc.SecondaryParents = secondaryParents
// txt += ` secondary_parent="` +
strings.Join(secondaryParents, `;`) + `"`
secondaryModeStr, secondaryModeWarnings :=
getSecondaryModeStr(dsParams.TryAllPrimariesBeforeSecondary, atsMajorVer,
tc.DeliveryServiceName(*ds.XMLID))
warnings = append(warnings, secondaryModeWarnings...)
// txt += secondaryModeStr
- txt.SecondaryMode = secondaryModeStr // TODO convert
+ pasvc.SecondaryMode = secondaryModeStr // TODO convert
}
- txt.RetryPolicy = getTopologyRoundRobin(ds, serverParams,
serverPlacement.IsLastCacheTier, dsParams.Algorithm)
+ pasvc.RetryPolicy = getTopologyRoundRobin(ds, serverParams,
serverPlacement.IsLastCacheTier, dsParams.Algorithm)
// txt += ` round_robin=` + getTopologyRoundRobin(ds, serverParams,
serverPlacement.IsLastCacheTier, dsParams.Algorithm)
- txt.GoDirect = getTopologyGoDirect(ds, serverPlacement.IsLastTier,
serverPlacement.IsLastCacheTier)
+ pasvc.GoDirect = getTopologyGoDirect(ds, serverPlacement)
// txt += ` go_direct=` + getTopologyGoDirect(ds,
serverPlacement.IsLastTier)
// TODO convert
@@ -1009,7 +1093,7 @@ func getTopologyParentConfigLine(
}
tqWarns := []string{}
- txt.IgnoreQueryStringInParentSelection, tqWarns =
getTopologyQueryStringIgnore(ds, serverParams, serverPlacement.IsLastCacheTier,
dsParams.Algorithm, useQueryStringInParentSelection)
+ pasvc.IgnoreQueryStringInParentSelection, tqWarns =
getTopologyQueryStringIgnore(ds, serverParams, serverPlacement,
dsParams.Algorithm, useQueryStringInParentSelection)
warnings = append(warnings, tqWarns...)
// txt += ` qstring=` + getTopologyQueryString(ds, serverParams,
serverPlacement.IsLastCacheTier, dsParams.Algorithm,
dsParams.QueryStringHandling)
@@ -1018,23 +1102,22 @@ func getTopologyParentConfigLine(
// txt += getTopologyParentIsProxyStr(serverPlacement.IsLastCacheTier)
// TODO convert
- prWarns := []string{}
- txt.MaxSimpleRetries, txt.MaxMarkdownRetries,
txt.MarkdownResponseCodes, txt.ErrorResponseCodes, prWarns =
getParentRetryStr(serverPlacement.IsLastCacheTier, atsMajorVer,
dsParams.ParentRetry, dsParams.UnavailableServerRetryResponses,
dsParams.MaxSimpleRetries, dsParams.MaxUnavailableServerRetries)
+ prWarns :=
dsParams.FillParentSvcRetries(serverPlacement.IsLastCacheTier, atsMajorVer,
pasvc)
warnings = append(warnings, prWarns...)
// txt += getParentRetryStr(serverPlacement.IsLastCacheTier,
atsMajorVer, dsParams.ParentRetry, dsParams.UnavailableServerRetryResponses,
dsParams.MaxSimpleRetries, dsParams.MaxUnavailableServerRetries)
// txt += "\n"
if dsParams.UsePeering {
- txt.SecondaryMode =
ParentAbstractionServiceParentSecondaryModePeering
+ pasvc.SecondaryMode =
ParentAbstractionServiceParentSecondaryModePeering
}
- return txt, warnings, nil
+ return pasvc, warnings, nil
}
-// getParentRetryStr builds the parent retry directive(s).
+// getParentRetries builds the parent retry directive(s).
//
-// Returns the MaxSimpleRetries, MaxMarkdownRetries, MarkdownResponseCodes,
and ErrorResponseCodes.
+// Returns the MaxSimpleRetries, MaxMarkdownRetries, ErrorREsponseCodes,
MarkdownResponseCodes.
//
// If atsMajorVer < 6, "" is returned (ATS 5 and below don't support retry
directives).
// If isLastCacheTier is false, "" is returned. This argument exists to
simplify usage.
@@ -1045,71 +1128,77 @@ func getTopologyParentConfigLine(
//
// Does not return errors. If any input is malformed, warnings are returned
and that value is set to -1.
//
-func getParentRetryStr(isLastCacheTier bool, atsMajorVer int, parentRetry
string, unavailableServerRetryResponses string, maxSimpleRetries string,
maxUnavailableServerRetries string) (int, int, []int, []int, []string) {
+func (dsparams parentDSParams) FillParentSvcRetries(isLastCacheTier bool,
atsMajorVer int, pasvc *ParentAbstractionService) []string {
warnings := []string{}
- if !isLastCacheTier || // allow !isLastCacheTier, to simplify usage.
- parentRetry == "" || // allow parentRetry to be empty, to
simplify usage.
+
+ if !dsparams.HasRetryParams || // allow parentRetry to be empty, to
simplify usage.
atsMajorVer < 6 { // ATS 5 and below don't support parent_retry
directives
// warnings = append(warnings, "ATS 5 doesn't support parent
retry, not using parent retry values")
- return -1, -1, nil, nil, warnings // TODO move to formatter?
+ pasvc.MaxSimpleRetries = -1
+ pasvc.MaxMarkdownRetries = -1
+ pasvc.ErrorResponseCodes = nil
+ pasvc.MarkdownResponseCodes = nil
+ return warnings
}
- err := error(nil)
+ // Set initial defaults
+ pasvc.MaxSimpleRetries = 0
+ pasvc.MaxMarkdownRetries = 0
+ pasvc.ErrorResponseCodes = []int{}
+ pasvc.MarkdownResponseCodes = []int{}
- maxSimpleRetriesInt := ParentConfigDSParamDefaultMaxSimpleRetries
- if maxSimpleRetries != "" {
- maxSimpleRetriesInt, err = strconv.Atoi(maxSimpleRetries)
- if err != nil {
- maxSimpleRetriesInt =
ParentConfigDSParamDefaultMaxSimpleRetries
- warnings = append(warnings, "malformed maxSimpleRetries
'"+maxSimpleRetries+"', using default "+strconv.Itoa(maxSimpleRetriesInt))
+ if isLastCacheTier {
+ pasvc.MaxSimpleRetries =
ParentConfigDSParamDefaultMaxSimpleRetries
+ pasvc.MaxMarkdownRetries =
ParentConfigDSParamDefaultMaxUnavailableServerRetries
+ }
+
+ if dsparams.MaxSimpleRetries != "" {
+ if retriesint, err := strconv.Atoi(dsparams.MaxSimpleRetries);
err == nil {
+ pasvc.MaxSimpleRetries = retriesint
+ } else {
+ warnings = append(warnings, "malformed maxSimpleRetries
'"+dsparams.MaxSimpleRetries+"', using default
"+strconv.Itoa(pasvc.MaxSimpleRetries))
}
}
- maxUnavailableServerRetriesInt :=
ParentConfigDSParamDefaultMaxUnavailableServerRetries
- if maxUnavailableServerRetries != "" {
- maxUnavailableServerRetriesInt, err =
strconv.Atoi(maxUnavailableServerRetries)
- if err != nil {
- maxUnavailableServerRetriesInt =
ParentConfigDSParamDefaultMaxUnavailableServerRetries
- warnings = append(warnings, "malformed
maxUnavailableServerRetries '"+maxUnavailableServerRetries+"', using default
"+strconv.Itoa(maxUnavailableServerRetriesInt))
+ if dsparams.MaxUnavailableServerRetries != "" {
+ if retriesint, err :=
strconv.Atoi(dsparams.MaxUnavailableServerRetries); err == nil {
+ pasvc.MaxMarkdownRetries = retriesint
+ } else {
+ warnings = append(warnings, "malformed
maxUnavailableServerRetries '"+dsparams.MaxUnavailableServerRetries+"', using
default "+strconv.Itoa(pasvc.MaxMarkdownRetries))
}
}
- unavailableServerRetryResponsesInts, err :=
ParseRetryResponses(unavailableServerRetryResponses)
- if err != nil {
- warnings = append(warnings, "malformed
unavailableServerRetryResponses '"+unavailableServerRetryResponses+"', using
default")
- unavailableServerRetryResponsesInts = []int{}
+ // simple retry responses only supported int ATS for 9.1.x and above
+ if simpleResponseInts, err :=
ParseRetryResponses(dsparams.SimpleServerRetryResponses); err == nil {
+ pasvc.ErrorResponseCodes = simpleResponseInts
+ } else {
+ warnings = append(warnings, "malformed
simpleServerRetryResponses '"+dsparams.SimpleServerRetryResponses+"', using
default")
}
- simpleRetryResponsesInts := []int{}
- // TODO add support for 9.1
- // simpleRetryResponsesInts, err :=
ParseRetryResponses(simpleRetryResponses)
- // if err != nil {
- // warnings = append(warnings, "malformed simpleRetryResponses
'"+simpleRetryResponses+"', using default")
- // simpleRetryResponsesInts = []int{}
- // }
+ if unavailResponseInts, err :=
ParseRetryResponses(dsparams.UnavailableServerRetryResponses); err == nil {
+ pasvc.MarkdownResponseCodes = unavailResponseInts
+ } else {
+ warnings = append(warnings, "malformed
unavailableServerRetryResponses '"+dsparams.UnavailableServerRetryResponses+"',
using default")
+ }
// TODO make consts
- switch strings.ToLower(strings.TrimSpace(parentRetry)) {
+ switch strings.ToLower(strings.TrimSpace(dsparams.ParentRetry)) {
case "simple_retry":
- unavailableServerRetryResponsesInts = []int{}
- if len(simpleRetryResponsesInts) == 0 {
- simpleRetryResponsesInts =
append(simpleRetryResponsesInts, DefaultSimpleRetryCodes...)
+ if len(pasvc.ErrorResponseCodes) == 0 {
+ pasvc.ErrorResponseCodes = DefaultSimpleRetryCodes
}
case "unavailable_server_retry":
- simpleRetryResponsesInts = []int{}
- if len(unavailableServerRetryResponsesInts) == 0 {
- unavailableServerRetryResponsesInts =
append(unavailableServerRetryResponsesInts,
DefaultUnavailableServerRetryCodes...)
+ if len(pasvc.MarkdownResponseCodes) == 0 {
+ pasvc.MarkdownResponseCodes =
DefaultUnavailableServerRetryCodes
}
case "both":
- if len(unavailableServerRetryResponsesInts) == 0 {
- unavailableServerRetryResponsesInts =
append(unavailableServerRetryResponsesInts,
DefaultUnavailableServerRetryCodes...)
+ if len(pasvc.ErrorResponseCodes) == 0 {
+ pasvc.ErrorResponseCodes = DefaultSimpleRetryCodes
}
- if len(simpleRetryResponsesInts) == 0 {
- simpleRetryResponsesInts =
append(simpleRetryResponsesInts, DefaultSimpleRetryCodes...)
+ if len(pasvc.MarkdownResponseCodes) == 0 {
+ pasvc.MarkdownResponseCodes =
DefaultUnavailableServerRetryCodes
}
default:
- unavailableServerRetryResponsesInts = []int{}
- simpleRetryResponsesInts = []int{}
}
// txt := ` parent_retry=` + parentRetry
@@ -1117,7 +1206,7 @@ func getParentRetryStr(isLastCacheTier bool, atsMajorVer
int, parentRetry string
// txt += ` unavailable_server_retry_responses=` +
unavailableServerRetryResponses
// }
// txt += ` max_simple_retries=` + maxSimpleRetries + `
max_unavailable_server_retries=` + maxUnavailableServerRetries
- return maxSimpleRetriesInt, maxUnavailableServerRetriesInt,
unavailableServerRetryResponsesInts, simpleRetryResponsesInts, warnings
+ return warnings
}
// getSecondaryModeStr returns the secondary_mode string, and any warnings.
@@ -1127,7 +1216,7 @@ func getSecondaryModeStr(tryAllPrimariesBeforeSecondary
bool, atsMajorVer int, d
return ParentAbstractionServiceParentSecondaryModeDefault,
warnings
}
if atsMajorVer < 8 {
- warnings = append(warnings, "DS '"+string(ds)+"' had Parameter
"+ParentConfigParamSecondaryMode+" but this cache is
"+strconv.Itoa(atsMajorVer)+" and secondary_mode isn't supported in ATS until
8. Not using!")
+ warnings = append(warnings, "DS '"+string(ds)+"' had Parameter
"+ParentConfigRetryKeysDefault.SecondaryMode+" but this cache is
"+strconv.Itoa(atsMajorVer)+" and secondary_mode isn't supported in ATS until
8. Not using!")
return ParentAbstractionServiceParentSecondaryModeDefault,
warnings
}
@@ -1152,7 +1241,7 @@ func getTopologyRoundRobin(
if !serverIsLastTier {
return ParentAbstractionServiceRetryPolicyConsistentHash
}
- if parentSelectAlg := serverParams[ParentConfigParamAlgorithm];
ds.OriginShield != nil && *ds.OriginShield != "" &&
strings.TrimSpace(parentSelectAlg) != "" {
+ if parentSelectAlg :=
serverParams[ParentConfigRetryKeysDefault.Algorithm]; ds.OriginShield != nil &&
*ds.OriginShield != "" && strings.TrimSpace(parentSelectAlg) != "" {
if policy :=
ParentSelectAlgorithmToParentAbstractionServiceRetryPolicy(parentSelectAlg);
policy != ParentAbstractionServiceRetryPolicyInvalid {
return policy
}
@@ -1163,17 +1252,14 @@ func getTopologyRoundRobin(
return ParentAbstractionServiceRetryPolicyConsistentHash
}
-func getTopologyGoDirect(ds *DeliveryService, serverIsLastTier bool,
serverIsLastCacheTier bool) bool {
- if serverIsLastCacheTier {
+func getTopologyGoDirect(ds *DeliveryService, serverPlacement
TopologyPlacement) bool {
+ if serverPlacement.IsLastCacheTier {
return true
- }
- if !serverIsLastTier {
+ } else if !serverPlacement.IsLastTier {
return false
- }
- if ds.OriginShield != nil && *ds.OriginShield != "" {
+ } else if ds.OriginShield != nil && *ds.OriginShield != "" {
return true
- }
- if ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin {
+ } else if ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin {
return false
}
return true
@@ -1182,12 +1268,12 @@ func getTopologyGoDirect(ds *DeliveryService,
serverIsLastTier bool, serverIsLas
func getTopologyQueryStringIgnore(
ds *DeliveryService,
serverParams map[string]string,
- serverIsLastTier bool,
+ serverPlacement TopologyPlacement,
algorithm ParentAbstractionServiceRetryPolicy,
qStringHandling *bool,
) (bool, []string) {
warnings := []string{}
- if serverIsLastTier {
+ if serverPlacement.IsLastCacheTier {
if ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin &&
qStringHandling == nil && algorithm ==
ParentAbstractionServiceRetryPolicyConsistentHash && ds.QStringIgnore != nil &&
tc.QStringIgnore(*ds.QStringIgnore) == tc.QStringIgnoreUseInCacheKeyAndPassUp {
return false, warnings
}
@@ -1845,7 +1931,7 @@ func getServerParentConfigParams(server *Server,
allParentConfigParams []paramet
name := pa.Name
val := pa.Value
if name == ParentConfigParamQStringHandling ||
- name == ParentConfigParamAlgorithm ||
+ name == ParentConfigRetryKeysDefault.Algorithm ||
name == ParentConfigParamQString {
serverParams[name] = val
}
diff --git a/lib/go-atscfg/parentdotconfig_test.go
b/lib/go-atscfg/parentdotconfig_test.go
index 239fed2b7a..25595c37c9 100644
--- a/lib/go-atscfg/parentdotconfig_test.go
+++ b/lib/go-atscfg/parentdotconfig_test.go
@@ -53,7 +53,7 @@ func TestMakeParentDotConfig(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -164,7 +164,7 @@ func TestMakeParentDotConfigCapabilities(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -308,7 +308,7 @@ func TestMakeParentDotConfigMSOSecondaryParent(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -402,6 +402,10 @@ func TestMakeParentDotConfigMSOSecondaryParent(t
*testing.T) {
if !strings.Contains(txtx,
`secondary_parent="my-parent-1.my-parent-1-domain`) {
t.Errorf("expected secondary parent
'my-parent-1.my-parent-1-domain', actual: '%v'", txt)
}
+
+ if strings.Contains(txtx, "parent_retry") {
+ t.Errorf("Did not expect parent_retry parameter at edge/inner:
'%v'", txt)
+ }
}
func TestMakeParentDotConfigMSONoPrimaryParent(t *testing.T) {
@@ -423,7 +427,7 @@ func TestMakeParentDotConfigMSONoPrimaryParent(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -547,7 +551,7 @@ func TestMakeParentDotConfigTopologies(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -689,7 +693,7 @@ func TestMakeParentDotConfigNotInTopologies(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -829,7 +833,7 @@ func TestMakeParentDotConfigTopologiesCapabilities(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -977,7 +981,7 @@ func TestMakeParentDotConfigTopologiesOmitOfflineParents(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1120,7 +1124,7 @@ func
TestMakeParentDotConfigTopologiesOmitDifferentCDNParents(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1254,7 +1258,7 @@ func TestMakeParentDotConfigTopologiesMSO(t *testing.T) {
parentConfigParams := []tc.Parameter{
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1445,7 +1449,7 @@ func
TestMakeParentDotConfigTopologiesMSOWithCapabilities(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1585,7 +1589,7 @@ func TestMakeParentDotConfigMSOWithCapabilities(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1715,7 +1719,7 @@ func TestMakeParentDotConfigTopologiesMSOParams(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1727,33 +1731,33 @@ func TestMakeParentDotConfigTopologiesMSOParams(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMSOAlgorithm,
+ Name: ParentConfigRetryKeysMSO.Algorithm,
ConfigFile: "parent.config",
Value: "consistent_hash",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMSOParentRetry,
+ Name: ParentConfigRetryKeysMSO.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMSOUnavailableServerRetryResponses,
+ Name: ParentConfigRetryKeysMSO.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMSOMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysMSO.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMSOMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysMSO.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
}
@@ -1891,7 +1895,7 @@ func TestMakeParentDotConfigTopologiesParams(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1903,33 +1907,33 @@ func TestMakeParentDotConfigTopologiesParams(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: "consistent_hash",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamParentRetry,
+ Name: ParentConfigRetryKeysDefault.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamUnavailableServerRetryResponses,
+ Name:
ParentConfigRetryKeysDefault.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysDefault.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysDefault.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
}
@@ -2070,7 +2074,7 @@ func
TestMakeParentDotConfigTopologiesNonStandardServerTypes(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2218,7 +2222,7 @@ func TestMakeParentDotConfigSecondaryMode(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2230,7 +2234,13 @@ func TestMakeParentDotConfigSecondaryMode(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamSecondaryMode,
+ Name: ParentConfigRetryKeysDefault.SecondaryMode,
+ ConfigFile: "parent.config",
+ Value: "",
+ Profiles: []byte(`["ds0Profile","ds1Profile"]`),
+ },
+ tc.Parameter{
+ Name: ParentConfigRetryKeysFirst.SecondaryMode,
ConfigFile: "parent.config",
Value: "",
Profiles: []byte(`["ds0Profile","ds1Profile"]`),
@@ -2379,7 +2389,7 @@ func TestMakeParentDotConfigNoSecondaryMode(t *testing.T)
{
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2536,7 +2546,7 @@ func TestMakeParentDotConfigComments(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2662,7 +2672,7 @@ func TestMakeParentDotConfigCommentTopology(t *testing.T)
{
Profiles: []byte(`["serverprofile"]`),
},
{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2816,7 +2826,7 @@ func TestMakeParentDotConfigHTTPSOrigin(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -2933,7 +2943,7 @@ func TestMakeParentDotConfigHTTPSOriginTopology(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -3067,7 +3077,7 @@ func TestMakeParentDotConfigNoParentNoTopology(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -3196,7 +3206,7 @@ func
TestMakeParentDotConfigHTTPSOriginTopologyNoPrimaryParent(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -3334,7 +3344,7 @@ func TestMakeParentDotConfigMergeParentGroupTopology(t
*testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -3543,7 +3553,7 @@ func
TestMakeParentDotConfigTopologiesServerMultipleProfileParams(t *testing.T)
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -3555,33 +3565,33 @@ func
TestMakeParentDotConfigTopologiesServerMultipleProfileParams(t *testing.T)
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: "consistent_hash",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamParentRetry,
+ Name: ParentConfigRetryKeysDefault.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamUnavailableServerRetryResponses,
+ Name:
ParentConfigRetryKeysDefault.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysDefault.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysDefault.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
@@ -3710,6 +3720,745 @@ func
TestMakeParentDotConfigTopologiesServerMultipleProfileParams(t *testing.T)
}
}
+func TestMakeParentDotConfigFirstLastNoTopo(t *testing.T) {
+ hdr := &ParentConfigOpts{AddComments: true, HdrComment:
"myHeaderComment"}
+
+ // Non Toplogy ds
+ ds0 := makeParentDS()
+ ds0Type := tc.DSTypeHTTP
+ ds0.Type = &ds0Type
+ ds0.QStringIgnore =
util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
+ ds0.OrgServerFQDN = util.StrPtr("https://ds0.example.net")
+ ds0.ProfileID = util.IntPtr(311)
+ ds0.ProfileName = util.StrPtr("ds0Profile")
+
+ // Non Toplogy ds, MSO
+ ds1 := makeParentDS()
+ ds1Type := tc.DSTypeHTTP
+ ds1.Type = &ds1Type
+ ds1.QStringIgnore =
util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
+ ds1.OrgServerFQDN = util.StrPtr("https://ds1.example.net")
+ ds1.ProfileID = util.IntPtr(312)
+ ds1.ProfileName = util.StrPtr("ds0Profile")
+ ds1.MultiSiteOrigin = util.BoolPtr(true)
+
+ dses := []DeliveryService{*ds0, *ds1}
+
+ parentConfigParams := []tc.Parameter{
+ {
+ Name: ParentConfigParamQStringHandling,
+ ConfigFile: "parent.config",
+ Value: "myQStringHandlingParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigRetryKeysDefault.Algorithm,
+ ConfigFile: "parent.config",
+ Value: tc.AlgorithmConsistentHash,
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigParamQString,
+ ConfigFile: "parent.config",
+ Value: "myQstringParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ }
+
+ // Create set of DS params
+ params := map[string]string{
+ ParentConfigRetryKeysDefault.Algorithm: "strict",
+ ParentConfigRetryKeysMSO.Algorithm: "strict",
+ ParentConfigRetryKeysFirst.Algorithm: "true",
+ ParentConfigRetryKeysInner.Algorithm: "latched",
+ ParentConfigRetryKeysLast.Algorithm: "true",
+
+ ParentConfigRetryKeysDefault.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysMSO.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysFirst.SecondaryMode: "alternate",
+ ParentConfigRetryKeysInner.SecondaryMode: "peering",
+ ParentConfigRetryKeysLast.SecondaryMode: "alternate",
+
+ ParentConfigRetryKeysMSO.ParentRetry:
"unavailable_server_retry",
+ ParentConfigRetryKeysFirst.ParentRetry: "both",
+ ParentConfigRetryKeysInner.ParentRetry: "both",
+ ParentConfigRetryKeysLast.ParentRetry: "both",
+
+ ParentConfigRetryKeysDefault.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysMSO.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysFirst.MaxSimpleRetries: "12",
+ ParentConfigRetryKeysInner.MaxSimpleRetries: "13",
+ ParentConfigRetryKeysLast.MaxSimpleRetries: "14",
+
+ ParentConfigRetryKeysDefault.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysMSO.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysFirst.SimpleRetryResponses: `"401,402"`,
+ ParentConfigRetryKeysInner.SimpleRetryResponses: `"401,403"`,
+ ParentConfigRetryKeysLast.SimpleRetryResponses: `"401,404"`,
+
+ ParentConfigRetryKeysDefault.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysMSO.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysFirst.MaxUnavailableRetries: "22",
+ ParentConfigRetryKeysInner.MaxUnavailableRetries: "23",
+ ParentConfigRetryKeysLast.MaxUnavailableRetries: "24",
+
+ ParentConfigRetryKeysDefault.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysMSO.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysFirst.UnavailableRetryResponses:
`"501,502"`,
+ ParentConfigRetryKeysInner.UnavailableRetryResponses:
`"501,503"`,
+ ParentConfigRetryKeysLast.UnavailableRetryResponses:
`"501,504"`,
+ }
+
+ // Assign them to the profile
+ for key, val := range params {
+ tcparam := tc.Parameter{
+ Name: key,
+ ConfigFile: "parent.config",
+ Value: val,
+ Profiles: []byte(`["ds0Profile"]`),
+ }
+ parentConfigParams = append(parentConfigParams, tcparam)
+ }
+
+ serverParams := []tc.Parameter{
+ {
+ Name: "trafficserver",
+ ConfigFile: "package",
+ Value: "9",
+ Profiles: []byte(`["global"]`),
+ },
+ }
+
+ edge := makeTestParentServer()
+ edge.Cachegroup = util.StrPtr("edgeCG")
+ edge.CachegroupID = util.IntPtr(400)
+
+ mid0 := makeTestParentServer()
+ mid0.Cachegroup = util.StrPtr("midCG0")
+ mid0.CachegroupID = util.IntPtr(500)
+ mid0.HostName = util.StrPtr("mymid0")
+ mid0.ID = util.IntPtr(45)
+ setIP(mid0, "192.168.2.2")
+
+ mid1 := makeTestParentServer()
+ mid1.Cachegroup = util.StrPtr("midCG1")
+ mid1.CachegroupID = util.IntPtr(501)
+ mid1.HostName = util.StrPtr("mymid1")
+ mid1.ID = util.IntPtr(46)
+ setIP(mid0, "192.168.2.3")
+
+ org0 := makeTestParentServer()
+ org0.Cachegroup = util.StrPtr("orgCG0")
+ org0.CachegroupID = util.IntPtr(502)
+ org0.HostName = util.StrPtr("myorg0")
+ org0.ID = util.IntPtr(47)
+ setIP(org0, "192.168.2.4")
+ org0.Type = tc.OriginTypeName
+ org0.TypeID = util.IntPtr(991)
+
+ org1 := makeTestParentServer()
+ org1.Cachegroup = util.StrPtr("orgCG1")
+ org1.CachegroupID = util.IntPtr(503)
+ org1.HostName = util.StrPtr("myorg1")
+ org1.ID = util.IntPtr(48)
+ setIP(org1, "192.168.2.5")
+ org1.Type = tc.OriginTypeName
+ org1.TypeID = util.IntPtr(991)
+
+ servers := []Server{*edge, *mid0, *mid1, *org0, *org1}
+
+ topologies := []tc.Topology{
+ {
+ Name: "t0",
+ Nodes: []tc.TopologyNode{
+ {
+ Cachegroup: "edgeCG",
+ Parents: []int{1, 2},
+ },
+ {
+ Cachegroup: "midCG0",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "midCG1",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "orgCG0",
+ },
+ {
+ Cachegroup: "orgCG1",
+ },
+ },
+ },
+ }
+
+ serverCapabilities := map[int]map[ServerCapability]struct{}{}
+ dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}
+
+ eCG := &tc.CacheGroupNullable{}
+ eCG.Name = edge.Cachegroup
+ eCG.ID = edge.CachegroupID
+ eCG.ParentName = mid0.Cachegroup
+ eCG.ParentCachegroupID = mid0.CachegroupID
+ eCG.SecondaryParentName = mid1.Cachegroup
+ eCG.SecondaryParentCachegroupID = mid1.CachegroupID
+ eCGType := tc.CacheGroupEdgeTypeName
+ eCG.Type = &eCGType
+
+ mCG0 := &tc.CacheGroupNullable{}
+ mCG0.Name = mid0.Cachegroup
+ mCG0.ID = mid0.CachegroupID
+ mCG0.ParentName = org0.Cachegroup
+ mCG0.ParentCachegroupID = org0.CachegroupID
+ mCG0.SecondaryParentName = org1.Cachegroup
+ mCG0.SecondaryParentCachegroupID = org1.CachegroupID
+ mCGType0 := tc.CacheGroupMidTypeName
+ mCG0.Type = &mCGType0
+
+ mCG1 := &tc.CacheGroupNullable{}
+ mCG1.Name = mid1.Cachegroup
+ mCG1.ID = mid1.CachegroupID
+ mCG1.ParentName = org1.Cachegroup
+ mCG1.ParentCachegroupID = org1.CachegroupID
+ mCG1.SecondaryParentName = org0.Cachegroup
+ mCG1.SecondaryParentCachegroupID = org0.CachegroupID
+ mCGType1 := tc.CacheGroupMidTypeName
+ mCG1.Type = &mCGType1
+
+ oCG0 := &tc.CacheGroupNullable{}
+ oCG0.Name = org0.Cachegroup
+ oCG0.ID = org0.CachegroupID
+ oCGType0 := tc.CacheGroupOriginTypeName
+ oCG0.Type = &oCGType0
+
+ oCG1 := &tc.CacheGroupNullable{}
+ oCG1.Name = org1.Cachegroup
+ oCG1.ID = org1.CachegroupID
+ oCGType1 := tc.CacheGroupOriginTypeName
+ oCG1.Type = &oCGType1
+
+ cgs := []tc.CacheGroupNullable{*eCG, *mCG0, *mCG1, *oCG0, *oCG1}
+
+ dss := []DeliveryServiceServer{
+ {Server: *edge.ID, DeliveryService: *ds0.ID},
+ {Server: *mid0.ID, DeliveryService: *ds0.ID},
+ {Server: *mid1.ID, DeliveryService: *ds0.ID},
+ {Server: *org0.ID, DeliveryService: *ds0.ID},
+ {Server: *org1.ID, DeliveryService: *ds0.ID},
+
+ {Server: *edge.ID, DeliveryService: *ds1.ID},
+ {Server: *mid0.ID, DeliveryService: *ds1.ID},
+ {Server: *mid1.ID, DeliveryService: *ds1.ID},
+ {Server: *org0.ID, DeliveryService: *ds1.ID},
+ {Server: *org1.ID, DeliveryService: *ds1.ID},
+ }
+ cdn := &tc.CDN{
+ DomainName: "cdndomain.example",
+ Name: "my-cdn-name",
+ }
+
+ dsstrs := []string{
+ `dest_domain=ds0.example.net `,
+ `dest_domain=ds1.example.net `,
+ }
+
+ { // test edge config
+ cfg, err := MakeParentDotConfig(dses, edge, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, hdr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, hdr.HdrComment)
+
+ needs := []string{
+ ` secondary_mode=2`,
+ ` round_robin=consistent_hash`,
+ ` go_direct=false`,
+ ` parent_is_proxy=true`,
+ ` parent_retry=both`,
+ ` max_simple_retries=12`,
+ ` max_unavailable_server_retries=22`,
+ ` simple_server_retry_responses="401,402"`,
+ ` unavailable_server_retry_responses="501,502"`,
+ }
+
+ for _, dsstr := range dsstrs {
+ cnt := strings.Count(txt, dsstr)
+ if 1 != cnt {
+ t.Errorf("Expected one entry for %s got
%d\n%v", dsstr, cnt, txt)
+ } else {
+ lines := strings.Split(txt, "\n")
+ dsline := lineWhichContains(lines, dsstr)
+ missing := missingFrom(dsline, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s)
from line: %v\n%v", missing, dsline)
+ }
+ }
+ }
+ }
+
+ { // test mid config
+ cfg, err := MakeParentDotConfig(dses, mid0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, hdr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, hdr.HdrComment)
+
+ needs := []string{
+ ` round_robin=true`,
+ ` go_direct=true`,
+ ` parent_is_proxy=false`,
+ ` parent_retry=both`,
+ ` max_simple_retries=12`,
+ ` max_unavailable_server_retries=22`,
+ ` simple_server_retry_responses="401,402"`,
+ ` unavailable_server_retry_responses="501,502"`,
+ }
+
+ {
+ dsstr := "dest_domain=ds1.example.net"
+ cnt := strings.Count(txt, dsstr)
+ if 1 != cnt {
+ t.Errorf("Expected one entry for %s got
%d\n%v", dsstr, cnt, txt)
+ } else {
+ lines := strings.Split(txt, "\n")
+ dsline := lineWhichContains(lines, dsstr)
+ missing := missingFrom(dsline, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s)
from line: %v\n%v", missing, dsline)
+ }
+ }
+ }
+ }
+}
+
+func TestMakeParentDotConfigFirstInnerLastTopology(t *testing.T) {
+ hdr := &ParentConfigOpts{AddComments: true, HdrComment:
"myHeaderComment"}
+
+ // Toplogy ds, MSO
+ ds0 := makeParentDS()
+ ds0Type := tc.DSTypeHTTP
+ ds0.Type = &ds0Type
+ ds0.QStringIgnore =
util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
+ ds0.OrgServerFQDN = util.StrPtr("http://ds0.example.net")
+ ds0.ProfileID = util.IntPtr(311)
+ ds0.ProfileName = util.StrPtr("ds0Profile")
+ ds0.MultiSiteOrigin = util.BoolPtr(true)
+ ds0.Topology = util.StrPtr("t0")
+
+ // Toplogy ds, non MSO
+ ds1 := makeParentDS()
+ ds1.ID = util.IntPtr(44)
+ ds1Type := tc.DSTypeHTTP
+ ds1.Type = &ds1Type
+ ds1.QStringIgnore =
util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
+ ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
+ ds1.ProfileID = util.IntPtr(311)
+ ds1.ProfileName = util.StrPtr("ds0Profile")
+ ds1.Topology = util.StrPtr("t0")
+
+ dses := []DeliveryService{*ds0, *ds1}
+
+ parentConfigParams := []tc.Parameter{
+ {
+ Name: ParentConfigParamQStringHandling,
+ ConfigFile: "parent.config",
+ Value: "myQStringHandlingParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigRetryKeysDefault.Algorithm,
+ ConfigFile: "parent.config",
+ Value: tc.AlgorithmConsistentHash,
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigParamQString,
+ ConfigFile: "parent.config",
+ Value: "myQstringParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ }
+
+ // Create set of DS params
+ params := map[string]string{
+ ParentConfigRetryKeysDefault.Algorithm: "strict",
+ ParentConfigRetryKeysMSO.Algorithm: "strict",
+ ParentConfigRetryKeysFirst.Algorithm: "true",
+ ParentConfigRetryKeysInner.Algorithm: "latched",
+ ParentConfigRetryKeysLast.Algorithm: "true",
+
+ ParentConfigRetryKeysDefault.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysMSO.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysFirst.SecondaryMode: "alternate",
+ ParentConfigRetryKeysInner.SecondaryMode: "peering",
+ ParentConfigRetryKeysLast.SecondaryMode: "alternate",
+
+ ParentConfigRetryKeysMSO.ParentRetry:
"unavailable_server_retry",
+ ParentConfigRetryKeysFirst.ParentRetry: "both",
+ ParentConfigRetryKeysInner.ParentRetry: "both",
+ ParentConfigRetryKeysLast.ParentRetry: "both",
+
+ ParentConfigRetryKeysDefault.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysMSO.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysFirst.MaxSimpleRetries: "12",
+ ParentConfigRetryKeysInner.MaxSimpleRetries: "13",
+ ParentConfigRetryKeysLast.MaxSimpleRetries: "14",
+
+ ParentConfigRetryKeysDefault.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysMSO.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysFirst.SimpleRetryResponses: `"401,402"`,
+ ParentConfigRetryKeysInner.SimpleRetryResponses: `"401,403"`,
+ ParentConfigRetryKeysLast.SimpleRetryResponses: `"401,404"`,
+
+ ParentConfigRetryKeysDefault.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysMSO.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysFirst.MaxUnavailableRetries: "22",
+ ParentConfigRetryKeysInner.MaxUnavailableRetries: "23",
+ ParentConfigRetryKeysLast.MaxUnavailableRetries: "24",
+
+ ParentConfigRetryKeysDefault.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysMSO.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysFirst.UnavailableRetryResponses:
`"501,502"`,
+ ParentConfigRetryKeysInner.UnavailableRetryResponses:
`"501,503"`,
+ ParentConfigRetryKeysLast.UnavailableRetryResponses:
`"501,504"`,
+ }
+
+ // Assign them to the profile
+ for key, val := range params {
+ tcparam := tc.Parameter{
+ Name: key,
+ ConfigFile: "parent.config",
+ Value: val,
+ Profiles: []byte(`["ds0Profile"]`),
+ }
+ parentConfigParams = append(parentConfigParams, tcparam)
+ }
+
+ serverParams := []tc.Parameter{
+ {
+ Name: "trafficserver",
+ ConfigFile: "package",
+ Value: "9",
+ Profiles: []byte(`["global"]`),
+ },
+ }
+
+ edge := makeTestParentServer()
+ edge.Cachegroup = util.StrPtr("edgeCG")
+ edge.CachegroupID = util.IntPtr(400)
+ edge.HostName = util.StrPtr("edge")
+
+ mid0 := makeTestParentServer()
+ mid0.Cachegroup = util.StrPtr("midCG0")
+ mid0.CachegroupID = util.IntPtr(500)
+ mid0.HostName = util.StrPtr("mid0")
+ mid0.ID = util.IntPtr(45)
+ setIP(mid0, "192.168.2.2")
+
+ mid1 := makeTestParentServer()
+ mid1.Cachegroup = util.StrPtr("midCG1")
+ mid1.CachegroupID = util.IntPtr(501)
+ mid1.HostName = util.StrPtr("mid1")
+ mid1.ID = util.IntPtr(46)
+ setIP(mid1, "192.168.2.3")
+
+ opl0 := makeTestParentServer()
+ opl0.Cachegroup = util.StrPtr("oplCG0")
+ opl0.CachegroupID = util.IntPtr(502)
+ opl0.HostName = util.StrPtr("opl0")
+ opl0.ID = util.IntPtr(47)
+ setIP(opl0, "192.168.2.4")
+
+ opl1 := makeTestParentServer()
+ opl1.Cachegroup = util.StrPtr("oplCG1")
+ opl1.CachegroupID = util.IntPtr(503)
+ opl1.HostName = util.StrPtr("opl1")
+ opl1.ID = util.IntPtr(48)
+ setIP(opl1, "192.168.2.5")
+
+ org0 := makeTestParentServer()
+ org0.Cachegroup = util.StrPtr("orgCG0")
+ org0.CachegroupID = util.IntPtr(504)
+ org0.HostName = util.StrPtr("org0")
+ org0.ID = util.IntPtr(49)
+ setIP(org0, "192.168.2.6")
+ org0.Type = tc.OriginTypeName
+ org0.TypeID = util.IntPtr(991)
+
+ org1 := makeTestParentServer()
+ org1.Cachegroup = util.StrPtr("orgCG1")
+ org1.CachegroupID = util.IntPtr(505)
+ org1.HostName = util.StrPtr("org1")
+ org1.ID = util.IntPtr(50)
+ setIP(org1, "192.168.2.7")
+ org1.Type = tc.OriginTypeName
+ org1.TypeID = util.IntPtr(991)
+
+ servers := []Server{*edge, *mid0, *mid1, *opl0, *opl1, *org0, *org1}
+
+ topologies := []tc.Topology{
+ {
+ Name: "t0",
+ Nodes: []tc.TopologyNode{
+ {
+ Cachegroup: "edgeCG",
+ Parents: []int{1, 2},
+ },
+ {
+ Cachegroup: "midCG0",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "midCG1",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "oplCG0",
+ Parents: []int{5, 6},
+ },
+ {
+ Cachegroup: "oplCG1",
+ Parents: []int{5, 6},
+ },
+ {
+ Cachegroup: "orgCG0",
+ },
+ {
+ Cachegroup: "orgCG1",
+ },
+ },
+ },
+ }
+
+ serverCapabilities := map[int]map[ServerCapability]struct{}{}
+ dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}
+
+ eCG := &tc.CacheGroupNullable{}
+ eCG.Name = edge.Cachegroup
+ eCG.ID = edge.CachegroupID
+ eCG.ParentName = mid0.Cachegroup
+ eCG.ParentCachegroupID = mid0.CachegroupID
+ eCG.SecondaryParentName = mid1.Cachegroup
+ eCG.SecondaryParentCachegroupID = mid1.CachegroupID
+ eCGType := tc.CacheGroupEdgeTypeName
+ eCG.Type = &eCGType
+
+ mCG0 := &tc.CacheGroupNullable{}
+ mCG0.Name = mid0.Cachegroup
+ mCG0.ID = mid0.CachegroupID
+ mCG0.ParentName = opl0.Cachegroup
+ mCG0.ParentCachegroupID = opl0.CachegroupID
+ mCG0.SecondaryParentName = opl1.Cachegroup
+ mCG0.SecondaryParentCachegroupID = opl1.CachegroupID
+ mCGType0 := tc.CacheGroupMidTypeName
+ mCG0.Type = &mCGType0
+
+ mCG1 := &tc.CacheGroupNullable{}
+ mCG1.Name = mid1.Cachegroup
+ mCG1.ID = mid1.CachegroupID
+ mCG1.ParentName = opl1.Cachegroup
+ mCG1.ParentCachegroupID = opl1.CachegroupID
+ mCG1.SecondaryParentName = opl0.Cachegroup
+ mCG1.SecondaryParentCachegroupID = opl0.CachegroupID
+ mCGType1 := tc.CacheGroupMidTypeName
+ mCG1.Type = &mCGType1
+
+ oplCG0 := &tc.CacheGroupNullable{}
+ oplCG0.Name = opl0.Cachegroup
+ oplCG0.ID = opl0.CachegroupID
+ oplCG0.ParentName = org0.Cachegroup
+ oplCG0.ParentCachegroupID = org0.CachegroupID
+ oplCG0.SecondaryParentName = org1.Cachegroup
+ oplCG0.SecondaryParentCachegroupID = org1.CachegroupID
+ oplCGType0 := tc.CacheGroupMidTypeName
+ oplCG0.Type = &oplCGType0
+
+ oplCG1 := &tc.CacheGroupNullable{}
+ oplCG1.Name = opl1.Cachegroup
+ oplCG1.ID = opl1.CachegroupID
+ oplCG1.ParentName = org1.Cachegroup
+ oplCG1.ParentCachegroupID = org1.CachegroupID
+ oplCG1.SecondaryParentName = org0.Cachegroup
+ oplCG1.SecondaryParentCachegroupID = org0.CachegroupID
+ oplCGType1 := tc.CacheGroupMidTypeName
+ oplCG1.Type = &oplCGType1
+
+ oCG0 := &tc.CacheGroupNullable{}
+ oCG0.Name = org0.Cachegroup
+ oCG0.ID = org0.CachegroupID
+ oCGType0 := tc.CacheGroupOriginTypeName
+ oCG0.Type = &oCGType0
+
+ oCG1 := &tc.CacheGroupNullable{}
+ oCG1.Name = org1.Cachegroup
+ oCG1.ID = org1.CachegroupID
+ oCGType1 := tc.CacheGroupOriginTypeName
+ oCG1.Type = &oCGType1
+
+ cgs := []tc.CacheGroupNullable{*eCG, *mCG0, *mCG1, *oplCG0, *oplCG1,
*oCG0, *oCG1}
+
+ dss := []DeliveryServiceServer{
+ /*
+ {Server: *edge.ID, DeliveryService: *ds0.ID},
+ {Server: *mid0.ID, DeliveryService: *ds0.ID},
+ {Server: *mid1.ID, DeliveryService: *ds0.ID},
+ {Server: *opl0.ID, DeliveryService: *ds0.ID},
+ {Server: *opl1.ID, DeliveryService: *ds0.ID},
+ {Server: *org0.ID, DeliveryService: *ds0.ID},
+ {Server: *org1.ID, DeliveryService: *ds0.ID},
+
+ {Server: *edge.ID, DeliveryService: *ds1.ID},
+ {Server: *mid0.ID, DeliveryService: *ds1.ID},
+ {Server: *mid1.ID, DeliveryService: *ds1.ID},
+ {Server: *opl0.ID, DeliveryService: *ds1.ID},
+ {Server: *opl1.ID, DeliveryService: *ds1.ID},
+ {Server: *org0.ID, DeliveryService: *ds1.ID},
+ {Server: *org1.ID, DeliveryService: *ds1.ID},
+ */
+ }
+ cdn := &tc.CDN{
+ DomainName: "cdndomain.example",
+ Name: "my-cdn-name",
+ }
+
+ dsstrs := []string{
+ `dest_domain=ds0.example.net `,
+ `dest_domain=ds1.example.net `,
+ }
+
+ { // test edge config
+ cfg, err := MakeParentDotConfig(dses, edge, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, hdr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, hdr.HdrComment)
+
+ needs := []string{
+ ` secondary_mode=2`,
+ ` round_robin=consistent_hash`,
+ ` go_direct=false`,
+ ` parent_is_proxy=true`,
+ ` parent_retry=both`,
+ ` max_simple_retries=12`,
+ ` max_unavailable_server_retries=22`,
+ ` simple_server_retry_responses="401,402"`,
+ ` unavailable_server_retry_responses="501,502"`,
+ }
+
+ for _, dsstr := range dsstrs {
+ cnt := strings.Count(txt, dsstr)
+ if 1 != cnt {
+ t.Errorf("Expected one entry for %s got
%d\n%v", dsstr, cnt, txt)
+ } else {
+ lines := strings.Split(txt, "\n")
+ dsline := lineWhichContains(lines, dsstr)
+ missing := missingFrom(dsline, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s)
from line: %v\n%v", missing, dsline)
+ }
+ }
+ }
+ }
+
+ { // test mid config
+ cfg, err := MakeParentDotConfig(dses, mid0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, hdr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, hdr.HdrComment)
+
+ needs := []string{
+ ` round_robin=consistent_hash`,
+ ` go_direct=false`,
+ ` parent_is_proxy=true`,
+ ` parent_retry=both`,
+ ` max_simple_retries=13`,
+ ` max_unavailable_server_retries=23`,
+ ` simple_server_retry_responses="401,403"`,
+ ` unavailable_server_retry_responses="501,503"`,
+ }
+
+ for _, dsstr := range dsstrs {
+ cnt := strings.Count(txt, dsstr)
+ if 1 != cnt {
+ t.Errorf("Expected one entry for %s got
%d\n%v", dsstr, cnt, txt)
+ } else {
+ lines := strings.Split(txt, "\n")
+ dsline := lineWhichContains(lines, dsstr)
+ missing := missingFrom(dsline, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s)
from line: %v\n%v", missing, dsline)
+ }
+ }
+ }
+ }
+
+ { // test opl config
+ cfg, err := MakeParentDotConfig(dses, opl0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, hdr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, hdr.HdrComment)
+
+ needs := []string{
+ ` round_robin=true`,
+ ` go_direct=true`,
+ ` parent_is_proxy=false`,
+ ` parent_retry=both`,
+ ` max_simple_retries=14`,
+ ` max_unavailable_server_retries=24`,
+ ` simple_server_retry_responses="401,404"`,
+ ` unavailable_server_retry_responses="501,504"`,
+ }
+
+ dsstr := `dest_domain=ds1.example.net `
+ cnt := strings.Count(txt, dsstr)
+ if 1 != cnt {
+ t.Errorf("Expected one entry for %s got %d\n%v", dsstr,
cnt, txt)
+ } else {
+ lines := strings.Split(txt, "\n")
+ dsline := lineWhichContains(lines, dsstr)
+ missing := missingFrom(dsline, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from line:
%v\n%v", missing, dsline)
+ }
+ }
+ }
+}
+
+// returns which elements in "needs" is missing from "line"
+func missingFrom(line string, needs []string) []string {
+ misses := []string{}
+ for _, need := range needs {
+ if !strings.Contains(line, need) {
+ misses = append(misses, need)
+ }
+ }
+ return misses
+}
+
+// returns first line which contains
+func lineWhichContains(lines []string, str string) (res string) {
+ for _, line := range lines {
+ if strings.Contains(line, str) {
+ res = line
+ break
+ }
+ }
+ return res
+}
+
// warningsContains returns whether the given warnings has str as a substring
of any warning.
// Note this is different than lib/go-util.ContainsStr, which only returns if
the array has the exact value as one of its values.
func warningsContains(warnings []string, str string) bool {
diff --git a/lib/go-atscfg/snidotyaml_test.go b/lib/go-atscfg/snidotyaml_test.go
index c7d67eb6a9..33d125a5a7 100644
--- a/lib/go-atscfg/snidotyaml_test.go
+++ b/lib/go-atscfg/snidotyaml_test.go
@@ -59,7 +59,7 @@ func TestMakeSNIDotYAMLH2(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -170,7 +170,7 @@ func TestMakeSNIDotYAMLH2(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name:
ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -223,7 +223,7 @@ func TestMakeSNIDotYAMLH2(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name:
ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -270,7 +270,7 @@ func TestMakeSNIDotYAMLH2(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name:
ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
diff --git a/lib/go-atscfg/sslservernamedotyaml_test.go
b/lib/go-atscfg/sslservernamedotyaml_test.go
index 659733d1e0..1d1ab82f2a 100644
--- a/lib/go-atscfg/sslservernamedotyaml_test.go
+++ b/lib/go-atscfg/sslservernamedotyaml_test.go
@@ -54,7 +54,7 @@ func TestMakeSSLServerNameYAML(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -174,7 +174,7 @@ func TestMakeSSLServerNameYAMLParams(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -306,7 +306,7 @@ func TestMakeSSLServerNameYAMLParamInvalid(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -442,7 +442,7 @@ func TestMakeSSLServerNameYAMLDSTLSVersions(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
diff --git a/lib/go-atscfg/strategiesdotconfig.go
b/lib/go-atscfg/strategiesdotconfig.go
index 0b2d46168c..b84b113bdf 100644
--- a/lib/go-atscfg/strategiesdotconfig.go
+++ b/lib/go-atscfg/strategiesdotconfig.go
@@ -155,10 +155,13 @@ func getStrategySecondaryMode(mode
ParentAbstractionServiceParentSecondaryMode)
}
func getStrategyErrorCodes(codes []int) string {
- str := ""
+ str := " ["
+ join := " "
for _, code := range codes {
- str += "\n" + ` - ` + strconv.Itoa(code)
+ str += join + strconv.Itoa(code)
+ join = ", "
}
+ str += " ]"
return str
}
diff --git a/lib/go-atscfg/strategiesdotconfig_test.go
b/lib/go-atscfg/strategiesdotconfig_test.go
index 88d5b0bcb1..a354cac29e 100644
--- a/lib/go-atscfg/strategiesdotconfig_test.go
+++ b/lib/go-atscfg/strategiesdotconfig_test.go
@@ -55,7 +55,7 @@ func TestMakeStrategiesDotConfig(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -179,7 +179,7 @@ func TestMakeStrategiesTopologiesParams(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -191,33 +191,33 @@ func TestMakeStrategiesTopologiesParams(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
- Value: "consistent_hash",
+ Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamParentRetry,
+ Name: ParentConfigRetryKeysDefault.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamUnavailableServerRetryResponses,
+ Name:
ParentConfigRetryKeysDefault.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysDefault.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysDefault.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
}
@@ -314,8 +314,8 @@ func TestMakeStrategiesTopologiesParams(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__myorigin0-dot-mydomain-dot-example-dot-net__80\nhost:myorigin0.mydomain.example.net",
}
@@ -353,7 +353,7 @@ func TestMakeStrategiesHTTPSOrigin(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -476,7 +476,7 @@ func TestMakeStrategiesPeeringRing(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -488,33 +488,33 @@ func TestMakeStrategiesPeeringRing(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
- Value: "consistent_hash",
+ Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamParentRetry,
+ Name: ParentConfigRetryKeysDefault.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamUnavailableServerRetryResponses,
+ Name:
ParentConfigRetryKeysDefault.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysDefault.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysDefault.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
}
@@ -629,8 +629,8 @@ func TestMakeStrategiesPeeringRing(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__ds1-dot-example-dot-net__80\nhost:ds1.example.net",
"groups:\n-*peers_group\n-*group_parents_ds1", // peer
ring group before parent group, param 'true'
}
@@ -666,8 +666,8 @@ func TestMakeStrategiesPeeringRing(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__ds1-dot-example-dot-net__80\nhost:ds1.example.net",
"groups:\n-*group_parents_ds1\nfailover:", // no peer
ring group, param is not 'true'
}
@@ -694,8 +694,8 @@ func TestMakeStrategiesPeeringRing(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__ds1-dot-example-dot-net__80\nhost:ds1.example.net",
"groups:\n-*group_parents_ds1\nfailover:", // no peer
ring group, no parameter
}
@@ -732,7 +732,7 @@ func TestMakeStrategiesPeeringRingMSO(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -744,33 +744,33 @@ func TestMakeStrategiesPeeringRingMSO(t *testing.T) {
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
- Value: "consistent_hash",
+ Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamParentRetry,
+ Name: ParentConfigRetryKeysDefault.ParentRetry,
ConfigFile: "parent.config",
Value: "both",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamUnavailableServerRetryResponses,
+ Name:
ParentConfigRetryKeysDefault.MaxSimpleRetries,
ConfigFile: "parent.config",
- Value: `"400,503"`,
+ Value: "14",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name: ParentConfigParamMaxSimpleRetries,
+ Name:
ParentConfigRetryKeysDefault.MaxUnavailableRetries,
ConfigFile: "parent.config",
- Value: "14",
+ Value: "9",
Profiles: []byte(`["ds1Profile"]`),
},
tc.Parameter{
- Name:
ParentConfigParamMaxUnavailableServerRetries,
+ Name:
ParentConfigRetryKeysDefault.UnavailableRetryResponses,
ConfigFile: "parent.config",
- Value: "9",
+ Value: `"400,503"`,
Profiles: []byte(`["ds1Profile"]`),
},
}
@@ -885,8 +885,8 @@ func TestMakeStrategiesPeeringRingMSO(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__myorigin0-dot-mydomain-dot-example-dot-net__80\nhost:myorigin0.mydomain.example.net",
"groups:\n-*peers_group\n-*group_parents_ds1", // peer
ring group before parent group, param 'true'
}
@@ -922,8 +922,8 @@ func TestMakeStrategiesPeeringRingMSO(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__myorigin0-dot-mydomain-dot-example-dot-net__80\nhost:myorigin0.mydomain.example.net",
"groups:\n-*group_parents_ds1\nfailover:", // no peer
ring group, param is not 'true'
}
@@ -950,8 +950,8 @@ func TestMakeStrategiesPeeringRingMSO(t *testing.T) {
"strategy:'strategy-ds1'",
"max_simple_retries:14",
"max_unavailable_retries:9",
- "response_codes:\n-404",
- "markdown_codes:\n-400\n-503",
+ "response_codes:[404]",
+ "markdown_codes:[400,503]",
"host__ds1__parent__myorigin0-dot-mydomain-dot-example-dot-net__80\nhost:myorigin0.mydomain.example.net",
"groups:\n-*group_parents_ds1\nfailover:", // no peer
ring group, no parameter
}
@@ -993,7 +993,7 @@ func TestMakeStrategiesPeeringRingNonTopology(t *testing.T)
{
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
- Name: ParentConfigParamAlgorithm,
+ Name: ParentConfigRetryKeysDefault.Algorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
@@ -1187,3 +1187,664 @@ func TestMakeStrategiesPeeringRingNonTopology(t
*testing.T) {
}
})
}
+
+func TestMakeStrategiesDotYAMLFirstLastNoTopoParams(t *testing.T) {
+ opt := &StrategiesYAMLOpts{VerboseComments: false, HdrComment:
"myHeaderComment"}
+
+ // Non Toplogy
+ ds0 := makeParentDS()
+ ds0.ID = util.IntPtr(42)
+ ds0Type := tc.DSTypeDNS
+ ds0.Type = &ds0Type
+ ds0.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
+ ds0.OrgServerFQDN = util.StrPtr("http://ds0.example.net")
+ ds0.ProfileID = util.IntPtr(310)
+ ds0.ProfileName = util.StrPtr("ds0Profile")
+
+ // Non Toplogy, MSO
+ ds1 := makeParentDS()
+ ds1.ID = util.IntPtr(43)
+ ds1Type := tc.DSTypeDNS
+ ds1.Type = &ds1Type
+ ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
+ ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
+ ds1.ProfileID = util.IntPtr(310)
+ ds1.ProfileName = util.StrPtr("ds0Profile")
+ ds1.MultiSiteOrigin = util.BoolPtr(true)
+
+ dsesall := []DeliveryService{*ds0, *ds1}
+
+ parentConfigParams := []tc.Parameter{
+ {
+ Name: ParentConfigParamQStringHandling,
+ ConfigFile: "parent.config",
+ Value: "myQStringHandlingParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigRetryKeysDefault.Algorithm,
+ ConfigFile: "parent.config",
+ Value: tc.AlgorithmConsistentHash,
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigParamQString,
+ ConfigFile: "parent.config",
+ Value: "myQstringParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ }
+
+ // Create set of DS params
+ params := map[string]string{
+ ParentConfigRetryKeysDefault.Algorithm: "strict",
+ ParentConfigRetryKeysMSO.Algorithm: "strict",
+ ParentConfigRetryKeysFirst.Algorithm: "true",
+ ParentConfigRetryKeysInner.Algorithm: "latched",
+ ParentConfigRetryKeysLast.Algorithm: "true",
+
+ ParentConfigRetryKeysDefault.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysMSO.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysFirst.SecondaryMode: "alternate",
+ ParentConfigRetryKeysInner.SecondaryMode: "peering",
+ ParentConfigRetryKeysLast.SecondaryMode: "alternate",
+
+ ParentConfigRetryKeysMSO.ParentRetry:
"unavailable_server_retry",
+ ParentConfigRetryKeysFirst.ParentRetry: "both",
+ ParentConfigRetryKeysInner.ParentRetry: "both",
+ ParentConfigRetryKeysLast.ParentRetry: "both",
+
+ ParentConfigRetryKeysDefault.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysMSO.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysFirst.MaxSimpleRetries: "12",
+ ParentConfigRetryKeysInner.MaxSimpleRetries: "13",
+ ParentConfigRetryKeysLast.MaxSimpleRetries: "14",
+
+ ParentConfigRetryKeysDefault.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysMSO.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysFirst.SimpleRetryResponses: `"401,402"`,
+ ParentConfigRetryKeysInner.SimpleRetryResponses: `"401,403"`,
+ ParentConfigRetryKeysLast.SimpleRetryResponses: `"401,404"`,
+
+ ParentConfigRetryKeysDefault.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysMSO.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysFirst.MaxUnavailableRetries: "22",
+ ParentConfigRetryKeysInner.MaxUnavailableRetries: "23",
+ ParentConfigRetryKeysLast.MaxUnavailableRetries: "24",
+
+ ParentConfigRetryKeysDefault.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysMSO.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysFirst.UnavailableRetryResponses:
`"501,502"`,
+ ParentConfigRetryKeysInner.UnavailableRetryResponses:
`"501,503"`,
+ ParentConfigRetryKeysLast.UnavailableRetryResponses:
`"501,504"`,
+ }
+
+ // Assign them to the profile
+ for key, val := range params {
+ tcparam := tc.Parameter{
+ Name: key,
+ ConfigFile: "parent.config",
+ Value: val,
+ Profiles: []byte(`["ds0Profile"]`),
+ }
+ parentConfigParams = append(parentConfigParams, tcparam)
+ }
+
+ serverParams := []tc.Parameter{
+ {
+ Name: "trafficserver",
+ ConfigFile: "package",
+ Value: "9",
+ Profiles: []byte(`["global"]`),
+ },
+ }
+
+ edge := makeTestParentServer()
+ edge.Cachegroup = util.StrPtr("edgeCG")
+ edge.CachegroupID = util.IntPtr(400)
+
+ mid0 := makeTestParentServer()
+ mid0.Cachegroup = util.StrPtr("midCG0")
+ mid0.CachegroupID = util.IntPtr(500)
+ mid0.HostName = util.StrPtr("mymid0")
+ mid0.ID = util.IntPtr(45)
+ setIP(mid0, "192.168.2.2")
+ mid0.Type = tc.CacheGroupMidTypeName
+ mid0.TypeID = util.IntPtr(990)
+
+ mid1 := makeTestParentServer()
+ mid1.Cachegroup = util.StrPtr("midCG1")
+ mid1.CachegroupID = util.IntPtr(501)
+ mid1.HostName = util.StrPtr("mymid1")
+ mid1.ID = util.IntPtr(46)
+ setIP(mid1, "192.168.2.3")
+ mid1.Type = tc.CacheGroupMidTypeName
+ mid1.TypeID = util.IntPtr(990)
+
+ org0 := makeTestParentServer()
+ org0.Cachegroup = util.StrPtr("orgCG0")
+ org0.CachegroupID = util.IntPtr(502)
+ org0.HostName = util.StrPtr("myorg0")
+ org0.ID = util.IntPtr(48)
+ setIP(org0, "192.168.2.4")
+ org0.Type = tc.OriginTypeName
+ org0.TypeID = util.IntPtr(991)
+
+ org1 := makeTestParentServer()
+ org1.Cachegroup = util.StrPtr("orgCG1")
+ org1.CachegroupID = util.IntPtr(503)
+ org1.HostName = util.StrPtr("myorg1")
+ org1.ID = util.IntPtr(49)
+ setIP(org1, "192.168.2.5")
+ org1.Type = tc.OriginTypeName
+ org1.TypeID = util.IntPtr(991)
+
+ servers := []Server{*edge, *mid0, *mid1, *org0, *org1}
+
+ topologies := []tc.Topology{
+ {
+ Name: "t0",
+ Nodes: []tc.TopologyNode{
+ {
+ Cachegroup: "edgeCG",
+ Parents: []int{1, 2},
+ },
+ {
+ Cachegroup: "midCG0",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "midCG1",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "orgCG0",
+ },
+ {
+ Cachegroup: "orgCG1",
+ },
+ },
+ },
+ }
+
+ serverCapabilities := map[int]map[ServerCapability]struct{}{}
+ dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}
+
+ eCG := &tc.CacheGroupNullable{}
+ eCG.Name = edge.Cachegroup
+ eCG.ID = edge.CachegroupID
+ eCG.ParentName = mid0.Cachegroup
+ eCG.ParentCachegroupID = mid0.CachegroupID
+ eCG.SecondaryParentName = mid1.Cachegroup
+ eCG.SecondaryParentCachegroupID = mid1.CachegroupID
+ eCGType := tc.CacheGroupEdgeTypeName
+ eCG.Type = &eCGType
+
+ mCG0 := &tc.CacheGroupNullable{}
+ mCG0.Name = mid0.Cachegroup
+ mCG0.ID = mid0.CachegroupID
+ mCG0.ParentName = org0.Cachegroup
+ mCG0.ParentCachegroupID = org0.CachegroupID
+ mCG0.SecondaryParentName = org1.Cachegroup
+ mCG0.SecondaryParentCachegroupID = org1.CachegroupID
+ mCGType0 := tc.CacheGroupMidTypeName
+ mCG0.Type = &mCGType0
+
+ mCG1 := &tc.CacheGroupNullable{}
+ mCG1.Name = mid1.Cachegroup
+ mCG1.ID = mid1.CachegroupID
+ mCG1.ParentName = org1.Cachegroup
+ mCG1.ParentCachegroupID = org1.CachegroupID
+ mCG1.SecondaryParentName = org0.Cachegroup
+ mCG1.SecondaryParentCachegroupID = org0.CachegroupID
+ mCGType1 := tc.CacheGroupMidTypeName
+ mCG1.Type = &mCGType1
+
+ oCG0 := &tc.CacheGroupNullable{}
+ oCG0.Name = org0.Cachegroup
+ oCG0.ID = org0.CachegroupID
+ oCGType0 := tc.CacheGroupOriginTypeName
+ oCG0.Type = &oCGType0
+
+ oCG1 := &tc.CacheGroupNullable{}
+ oCG1.Name = org1.Cachegroup
+ oCG1.ID = org1.CachegroupID
+ oCGType1 := tc.CacheGroupOriginTypeName
+ oCG1.Type = &oCGType1
+
+ cgs := []tc.CacheGroupNullable{*eCG, *mCG0, *mCG1, *oCG0, *oCG1}
+
+ dss := []DeliveryServiceServer{
+ {Server: *edge.ID, DeliveryService: *ds0.ID},
+ {Server: *mid0.ID, DeliveryService: *ds0.ID},
+ {Server: *mid1.ID, DeliveryService: *ds0.ID},
+ {Server: *org0.ID, DeliveryService: *ds0.ID},
+ {Server: *org1.ID, DeliveryService: *ds0.ID},
+
+ {Server: *edge.ID, DeliveryService: *ds1.ID},
+ {Server: *mid0.ID, DeliveryService: *ds1.ID},
+ {Server: *mid1.ID, DeliveryService: *ds1.ID},
+ {Server: *org0.ID, DeliveryService: *ds1.ID},
+ {Server: *org1.ID, DeliveryService: *ds1.ID},
+ }
+ cdn := &tc.CDN{
+ DomainName: "cdndomain.example",
+ Name: "my-cdn-name",
+ }
+
+ // edge config
+ /*
+ for _, ds := range dsesall {
+ dses := []DeliveryService{ds}
+ cfg, err := MakeStrategiesDotYAML(dses, edge, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, opt.HdrComment)
+
+ needs := []string{
+ ` policy: consistent_hash`,
+ ` go_direct: false`,
+ ` max_simple_retries: 12`,
+ ` max_unavailable_retries: 22`,
+ ` response_codes: [ 401, 402 ]`,
+ ` markdown_codes: [ 501, 502 ]`,
+ }
+
+ missing := missingFrom(txt, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from line:
%v\n%v", missing, txt)
+ }
+ }
+ */
+
+ // test mid config, MS only
+ {
+ ds := dsesall[1]
+ dses := []DeliveryService{ds}
+ cfg, err := MakeStrategiesDotYAML(dses, mid0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, opt.HdrComment)
+
+ needs := []string{
+ ` policy: rr_ip`,
+ ` go_direct: true`,
+ ` max_simple_retries: 14`,
+ ` max_unavailable_retries: 24`,
+ ` response_codes: [ 401, 404 ]`,
+ ` markdown_codes: [ 501, 504 ]`,
+ }
+
+ missing := missingFrom(txt, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from ds/line:
%s/%v\n%v", *ds.XMLID, missing, txt)
+ }
+ }
+}
+
+func TestMakeStrategiesDotYAMLFirstInnerLastParams(t *testing.T) {
+ opt := &StrategiesYAMLOpts{VerboseComments: false, HdrComment:
"myHeaderComment"}
+
+ // Toplogy ds, MSO
+ ds0 := makeParentDS()
+ ds0Type := tc.DSTypeHTTP
+ ds0.Type = &ds0Type
+ ds0.QStringIgnore =
util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp))
+ ds0.OrgServerFQDN = util.StrPtr("http://ds0.example.net")
+ ds0.ProfileID = util.IntPtr(311)
+ ds0.ProfileName = util.StrPtr("ds0Profile")
+ ds0.MultiSiteOrigin = util.BoolPtr(true)
+ ds0.Topology = util.StrPtr("t0")
+
+ // Toplogy ds, non MSO
+ ds1 := makeParentDS()
+ ds1.ID = util.IntPtr(43)
+ ds1Type := tc.DSTypeDNS
+ ds1.Type = &ds1Type
+ ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
+ ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
+ ds1.ProfileID = util.IntPtr(311)
+ ds1.ProfileName = util.StrPtr("ds0Profile")
+ ds1.Topology = util.StrPtr("t0")
+
+ dsesall := []DeliveryService{*ds0, *ds1}
+
+ parentConfigParams := []tc.Parameter{
+ {
+ Name: ParentConfigParamQStringHandling,
+ ConfigFile: "parent.config",
+ Value: "myQStringHandlingParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigRetryKeysDefault.Algorithm,
+ ConfigFile: "parent.config",
+ Value: tc.AlgorithmConsistentHash,
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ {
+ Name: ParentConfigParamQString,
+ ConfigFile: "parent.config",
+ Value: "myQstringParam",
+ Profiles: []byte(`["serverprofile"]`),
+ },
+ }
+
+ // Create set of DS params
+ params := map[string]string{
+ ParentConfigRetryKeysDefault.Algorithm: "strict",
+ ParentConfigRetryKeysMSO.Algorithm: "strict",
+ ParentConfigRetryKeysFirst.Algorithm: "true",
+ ParentConfigRetryKeysInner.Algorithm: "latched",
+ ParentConfigRetryKeysLast.Algorithm: "true",
+
+ ParentConfigRetryKeysDefault.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysMSO.SecondaryMode: "exhaust",
+ ParentConfigRetryKeysFirst.SecondaryMode: "alternate",
+ ParentConfigRetryKeysInner.SecondaryMode: "peering",
+ ParentConfigRetryKeysLast.SecondaryMode: "alternate",
+
+ ParentConfigRetryKeysMSO.ParentRetry:
"unavailable_server_retry",
+ ParentConfigRetryKeysFirst.ParentRetry: "both",
+ ParentConfigRetryKeysInner.ParentRetry: "both",
+ ParentConfigRetryKeysLast.ParentRetry: "both",
+
+ ParentConfigRetryKeysDefault.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysMSO.MaxSimpleRetries: "11",
+ ParentConfigRetryKeysFirst.MaxSimpleRetries: "12",
+ ParentConfigRetryKeysInner.MaxSimpleRetries: "13",
+ ParentConfigRetryKeysLast.MaxSimpleRetries: "14",
+
+ ParentConfigRetryKeysDefault.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysMSO.SimpleRetryResponses: `"401"`,
+ ParentConfigRetryKeysFirst.SimpleRetryResponses: `"401,402"`,
+ ParentConfigRetryKeysInner.SimpleRetryResponses: `"401,403"`,
+ ParentConfigRetryKeysLast.SimpleRetryResponses: `"401,404"`,
+
+ ParentConfigRetryKeysDefault.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysMSO.MaxUnavailableRetries: "21",
+ ParentConfigRetryKeysFirst.MaxUnavailableRetries: "22",
+ ParentConfigRetryKeysInner.MaxUnavailableRetries: "23",
+ ParentConfigRetryKeysLast.MaxUnavailableRetries: "24",
+
+ ParentConfigRetryKeysDefault.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysMSO.UnavailableRetryResponses: `"501"`,
+ ParentConfigRetryKeysFirst.UnavailableRetryResponses:
`"501,502"`,
+ ParentConfigRetryKeysInner.UnavailableRetryResponses:
`"501,503"`,
+ ParentConfigRetryKeysLast.UnavailableRetryResponses:
`"501,504"`,
+ }
+
+ // Assign them to the profile
+ for key, val := range params {
+ tcparam := tc.Parameter{
+ Name: key,
+ ConfigFile: "parent.config",
+ Value: val,
+ Profiles: []byte(`["ds0Profile"]`),
+ }
+ parentConfigParams = append(parentConfigParams, tcparam)
+ }
+
+ serverParams := []tc.Parameter{
+ {
+ Name: "trafficserver",
+ ConfigFile: "package",
+ Value: "9",
+ Profiles: []byte(`["global"]`),
+ },
+ }
+
+ edge := makeTestParentServer()
+ edge.Cachegroup = util.StrPtr("edgeCG")
+ edge.CachegroupID = util.IntPtr(400)
+
+ mid0 := makeTestParentServer()
+ mid0.Cachegroup = util.StrPtr("midCG0")
+ mid0.CachegroupID = util.IntPtr(500)
+ mid0.HostName = util.StrPtr("mymid0")
+ mid0.ID = util.IntPtr(45)
+ setIP(mid0, "192.168.2.2")
+
+ mid1 := makeTestParentServer()
+ mid1.Cachegroup = util.StrPtr("midCG1")
+ mid1.CachegroupID = util.IntPtr(501)
+ mid1.HostName = util.StrPtr("mymid1")
+ mid1.ID = util.IntPtr(46)
+ setIP(mid1, "192.168.2.3")
+
+ opl0 := makeTestParentServer()
+ opl0.Cachegroup = util.StrPtr("oplCG0")
+ opl0.CachegroupID = util.IntPtr(502)
+ opl0.HostName = util.StrPtr("myopl0")
+ opl0.ID = util.IntPtr(46)
+ setIP(opl0, "192.168.2.4")
+
+ opl1 := makeTestParentServer()
+ opl1.Cachegroup = util.StrPtr("oplCG1")
+ opl1.CachegroupID = util.IntPtr(503)
+ opl1.HostName = util.StrPtr("myopl1")
+ opl1.ID = util.IntPtr(47)
+ setIP(opl1, "192.168.2.5")
+
+ org0 := makeTestParentServer()
+ org0.Cachegroup = util.StrPtr("orgCG0")
+ org0.CachegroupID = util.IntPtr(504)
+ org0.HostName = util.StrPtr("myorg0")
+ org0.ID = util.IntPtr(48)
+ setIP(org0, "192.168.2.6")
+ org0.Type = tc.OriginTypeName
+ org0.TypeID = util.IntPtr(991)
+
+ org1 := makeTestParentServer()
+ org1.Cachegroup = util.StrPtr("orgCG1")
+ org1.CachegroupID = util.IntPtr(505)
+ org1.HostName = util.StrPtr("myorg1")
+ org1.ID = util.IntPtr(49)
+ setIP(org1, "192.168.2.7")
+ org1.Type = tc.OriginTypeName
+ org1.TypeID = util.IntPtr(991)
+
+ servers := []Server{*edge, *mid0, *mid1, *opl0, *opl1, *org0, *org1}
+
+ topologies := []tc.Topology{
+ {
+ Name: "t0",
+ Nodes: []tc.TopologyNode{
+ {
+ Cachegroup: "edgeCG",
+ Parents: []int{1, 2},
+ },
+ {
+ Cachegroup: "midCG0",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "midCG1",
+ Parents: []int{3, 4},
+ },
+ {
+ Cachegroup: "oplCG0",
+ Parents: []int{5, 6},
+ },
+ {
+ Cachegroup: "oplCG1",
+ Parents: []int{5, 6},
+ },
+ {
+ Cachegroup: "orgCG0",
+ },
+ {
+ Cachegroup: "orgCG1",
+ },
+ },
+ },
+ }
+
+ serverCapabilities := map[int]map[ServerCapability]struct{}{}
+ dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{}
+
+ eCG := &tc.CacheGroupNullable{}
+ eCG.Name = edge.Cachegroup
+ eCG.ID = edge.CachegroupID
+ eCG.ParentName = mid0.Cachegroup
+ eCG.ParentCachegroupID = mid0.CachegroupID
+ eCG.SecondaryParentName = mid1.Cachegroup
+ eCG.SecondaryParentCachegroupID = mid1.CachegroupID
+ eCGType := tc.CacheGroupEdgeTypeName
+ eCG.Type = &eCGType
+
+ mCG0 := &tc.CacheGroupNullable{}
+ mCG0.Name = mid0.Cachegroup
+ mCG0.ID = mid0.CachegroupID
+ mCG0.ParentName = opl0.Cachegroup
+ mCG0.ParentCachegroupID = opl0.CachegroupID
+ mCG0.SecondaryParentName = opl1.Cachegroup
+ mCG0.SecondaryParentCachegroupID = opl1.CachegroupID
+ mCGType0 := tc.CacheGroupMidTypeName
+ mCG0.Type = &mCGType0
+
+ mCG1 := &tc.CacheGroupNullable{}
+ mCG1.Name = mid1.Cachegroup
+ mCG1.ID = mid1.CachegroupID
+ mCG1.ParentName = opl1.Cachegroup
+ mCG1.ParentCachegroupID = opl1.CachegroupID
+ mCG1.SecondaryParentName = opl0.Cachegroup
+ mCG1.SecondaryParentCachegroupID = opl0.CachegroupID
+ mCGType1 := tc.CacheGroupMidTypeName
+ mCG1.Type = &mCGType1
+
+ oplCG0 := &tc.CacheGroupNullable{}
+ oplCG0.Name = opl0.Cachegroup
+ oplCG0.ID = opl0.CachegroupID
+ oplCG0.ParentName = org0.Cachegroup
+ oplCG0.ParentCachegroupID = org0.CachegroupID
+ oplCG0.SecondaryParentName = org1.Cachegroup
+ oplCG0.SecondaryParentCachegroupID = org1.CachegroupID
+ oplCGType0 := tc.CacheGroupMidTypeName
+ oplCG0.Type = &oplCGType0
+
+ oplCG1 := &tc.CacheGroupNullable{}
+ oplCG1.Name = opl1.Cachegroup
+ oplCG1.ID = opl1.CachegroupID
+ oplCG1.ParentName = org1.Cachegroup
+ oplCG1.ParentCachegroupID = org1.CachegroupID
+ oplCG1.SecondaryParentName = org0.Cachegroup
+ oplCG1.SecondaryParentCachegroupID = org0.CachegroupID
+ oplCGType1 := tc.CacheGroupMidTypeName
+ oplCG1.Type = &oplCGType1
+
+ oCG0 := &tc.CacheGroupNullable{}
+ oCG0.Name = org0.Cachegroup
+ oCG0.ID = org0.CachegroupID
+ oCGType0 := tc.CacheGroupOriginTypeName
+ oCG0.Type = &oCGType0
+
+ oCG1 := &tc.CacheGroupNullable{}
+ oCG1.Name = org1.Cachegroup
+ oCG1.ID = org1.CachegroupID
+ oCGType1 := tc.CacheGroupOriginTypeName
+ oCG1.Type = &oCGType1
+
+ cgs := []tc.CacheGroupNullable{*eCG, *mCG0, *mCG1, *oplCG0, *oplCG1,
*oCG0, *oCG1}
+
+ dss := []DeliveryServiceServer{
+ {Server: *org0.ID, DeliveryService: *ds0.ID},
+ {Server: *org1.ID, DeliveryService: *ds0.ID},
+
+ {Server: *edge.ID, DeliveryService: *ds1.ID},
+ {Server: *mid0.ID, DeliveryService: *ds1.ID},
+ {Server: *mid1.ID, DeliveryService: *ds1.ID},
+ {Server: *opl0.ID, DeliveryService: *ds1.ID},
+ {Server: *opl1.ID, DeliveryService: *ds1.ID},
+ {Server: *org0.ID, DeliveryService: *ds1.ID},
+ {Server: *org1.ID, DeliveryService: *ds1.ID},
+ }
+ cdn := &tc.CDN{
+ DomainName: "cdndomain.example",
+ Name: "my-cdn-name",
+ }
+
+ // edge config
+ for _, ds := range dsesall {
+ dses := []DeliveryService{ds}
+ cfg, err := MakeStrategiesDotYAML(dses, edge, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, opt.HdrComment)
+
+ needs := []string{
+ ` policy: consistent_hash`,
+ ` go_direct: false`,
+ ` max_simple_retries: 12`,
+ ` max_unavailable_retries: 22`,
+ ` response_codes: [ 401, 402 ]`,
+ ` markdown_codes: [ 501, 502 ]`,
+ }
+
+ missing := missingFrom(txt, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from line:
%v\n%v", missing, txt)
+ }
+ }
+
+ // test mid config
+ for _, ds := range dsesall {
+ dses := []DeliveryService{ds}
+ cfg, err := MakeStrategiesDotYAML(dses, mid0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, opt.HdrComment)
+
+ needs := []string{
+ ` policy: consistent_hash`,
+ ` go_direct: false`,
+ ` max_simple_retries: 13`,
+ ` max_unavailable_retries: 23`,
+ ` response_codes: [ 401, 403 ]`,
+ ` markdown_codes: [ 501, 503 ]`,
+ }
+
+ missing := missingFrom(txt, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from ds/line:
%s/%v\n%v", *ds.XMLID, missing, txt)
+ }
+ }
+
+ // test opl config
+ for _, ds := range dsesall {
+ dses := []DeliveryService{ds}
+ cfg, err := MakeStrategiesDotYAML(dses, opl0, servers,
topologies, serverParams, parentConfigParams, serverCapabilities,
dsRequiredCapabilities, cgs, dss, cdn, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+ txt := cfg.Text
+
+ testComment(t, txt, opt.HdrComment)
+
+ needs := []string{
+ ` policy: rr_ip`,
+ ` go_direct: true`,
+ ` max_simple_retries: 14`,
+ ` max_unavailable_retries: 24`,
+ ` response_codes: [ 401, 404 ]`,
+ ` markdown_codes: [ 501, 504 ]`,
+ }
+
+ missing := missingFrom(txt, needs)
+ if 0 < len(missing) {
+ t.Errorf("Missing required string(s) from line:
%v\n%v", missing, txt)
+ }
+ }
+}