You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by em...@apache.org on 2017/07/26 18:44:04 UTC
[2/2] incubator-ariatosca git commit: ARIA-321 Provide Clearwater IMS
example
ARIA-321 Provide Clearwater IMS example
* Allows capabilities, interfaces, and properties to override parent
definition types only if the new type is a descendant of the overridden
type
* Fix bugs in model instrumentation (to allow ctx access to capability
properties and complex values)
* Fix to get_property intrinsic function
* Don't let scalar values be negative
* Doc fixes related to ARIA-277
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/a9fb6fad
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/a9fb6fad
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/a9fb6fad
Branch: refs/heads/ARIA-321-clearwater
Commit: a9fb6fad49fd57458f7ef2c553493eefe18bfb14
Parents: c2b8e65
Author: Tal Liron <ta...@gmail.com>
Authored: Tue Jul 18 17:25:27 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Wed Jul 26 13:43:41 2017 -0500
----------------------------------------------------------------------
README.rst | 2 +-
aria/modeling/functions.py | 4 +-
aria/modeling/service_instance.py | 13 +-
aria/orchestrator/context/common.py | 6 +-
.../execution_plugin/ctx_proxy/server.py | 39 +-
aria/storage/collection_instrumentation.py | 15 +-
aria/storage/core.py | 2 +-
.../clearwater/clearwater-single-static.yaml | 90 ++++
examples/clearwater/scripts/bono/create.sh | 5 +
examples/clearwater/scripts/bono/delete.sh | 0
examples/clearwater/scripts/dime/create.sh | 5 +
examples/clearwater/scripts/dime/delete.sh | 0
examples/clearwater/scripts/ellis/configure.sh | 14 +
examples/clearwater/scripts/ellis/create.sh | 5 +
examples/clearwater/scripts/ellis/delete.sh | 0
examples/clearwater/scripts/homer/create.sh | 13 +
examples/clearwater/scripts/homer/delete.sh | 0
examples/clearwater/scripts/homestead/create.sh | 10 +
examples/clearwater/scripts/homestead/delete.sh | 0
examples/clearwater/scripts/host/configure.sh | 157 ++++++
examples/clearwater/scripts/ralf/create.sh | 0
examples/clearwater/scripts/ralf/delete.sh | 0
examples/clearwater/scripts/sprout/create.sh | 12 +
examples/clearwater/scripts/sprout/delete.sh | 0
examples/clearwater/scripts/velum/create.sh | 8 +
examples/clearwater/scripts/velum/delete.sh | 0
examples/clearwater/types/cassandra.yaml | 5 +
examples/clearwater/types/clearwater.yaml | 473 +++++++++++++++++++
examples/clearwater/types/ims.yaml | 413 ++++++++++++++++
examples/clearwater/types/smtp.yaml | 18 +
examples/hello-world/hello-world.yaml | 38 ++
examples/hello-world/helloworld.yaml | 38 --
.../simple_v1_0/data_types.py | 15 +-
.../simple_v1_0/modeling/capabilities.py | 14 +-
.../simple_v1_0/modeling/data_types.py | 4 -
.../simple_v1_0/modeling/functions.py | 18 +-
.../simple_v1_0/modeling/interfaces.py | 14 +-
.../simple_v1_0/modeling/parameters.py | 27 +-
.../simple_v1_0/presentation/types.py | 8 +-
.../aria_extension_tosca/simple_v1_0/types.py | 19 +
tests/end2end/test_hello_world.py | 2 +-
.../execution_plugin/test_ctx_proxy_server.py | 48 +-
42 files changed, 1423 insertions(+), 131 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/README.rst
----------------------------------------------------------------------
diff --git a/README.rst b/README.rst
index b9a8213..1284808 100644
--- a/README.rst
+++ b/README.rst
@@ -91,7 +91,7 @@ This section will describe how to run a simple "Hello World" example.
First, provide ARIA with the ARIA "hello world" service-template and name it (e.g.
``my-service-template``)::
- aria service-templates store examples/hello-world/helloworld.yaml my-service-template
+ aria service-templates store examples/hello-world/hello-world.yaml my-service-template
Now create a service based on this service-template and name it (e.g. ``my-service``)::
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/modeling/functions.py
----------------------------------------------------------------------
diff --git a/aria/modeling/functions.py b/aria/modeling/functions.py
index 6544adf..d0ec0cf 100644
--- a/aria/modeling/functions.py
+++ b/aria/modeling/functions.py
@@ -20,6 +20,7 @@ Mechanism for evaluating intrinsic functions.
from ..parser.consumption import ConsumptionContext
from ..parser.exceptions import InvalidValueError
from ..utils.collections import OrderedDict
+from ..utils.type import full_type_name
from . import exceptions
@@ -89,7 +90,8 @@ def evaluate(value, container_holder, report_issues=False): # pylint: disable=to
if (evaluation is None) \
or (not hasattr(evaluation, 'value')) \
or (not hasattr(evaluation, 'final')):
- raise InvalidValueError('bad __evaluate__ implementation')
+ raise InvalidValueError('bad __evaluate__ implementation: {0}'
+ .format(full_type_name(value)))
evaluated = True
value = evaluation.value
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 889465c..bf7c8a5 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -591,14 +591,15 @@ class NodeBase(InstanceModelMixin):
@classmethod
def determine_state(cls, op_name, is_transitional):
- """ :returns the state the node should be in as a result of running the
- operation on this node.
+ """
+ :returns the state the node should be in as a result of running the operation on this node.
- e.g. if we are running tosca.interfaces.node.lifecycle.Standard.create, then
- the resulting state should either 'creating' (if the task just started) or 'created'
- (if the task ended).
+ E.g. if we are running tosca.interfaces.node.lifecycle.Standard.create, then
+ the resulting state should either 'creating' (if the task just started) or 'created'
+ (if the task ended).
- If the operation is not a standard tosca lifecycle operation, then we return None"""
+ If the operation is not a standard TOSCA lifecycle operation, then we return None.
+ """
state_type = 'transitional' if is_transitional else 'finished'
try:
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index f400142..c71edca 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -40,8 +40,12 @@ class BaseContext(object):
INSTRUMENTATION_FIELDS = (
modeling.models.Node.attributes,
modeling.models.Node.properties,
+ # TODO: modeling.models.Capability.attributes,
+ modeling.models.Capability.properties,
modeling.models.NodeTemplate.attributes,
- modeling.models.NodeTemplate.properties
+ modeling.models.NodeTemplate.properties,
+ # TODO: modeling.models.CapabilityTemplate.attributes,
+ modeling.models.CapabilityTemplate.properties
)
class PrefixedLogger(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/orchestrator/execution_plugin/ctx_proxy/server.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/server.py b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
index ca910e0..d69f841 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/server.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
@@ -157,11 +157,11 @@ def _process_ctx_request(ctx, args):
while index < num_args:
arg = args[index]
attr = _desugar_attr(current, arg)
- if attr:
+ if attr is not None:
current = getattr(current, attr)
elif isinstance(current, collections.MutableMapping):
key = arg
- path_dict = _PathDictAccess(current)
+ path_dict = _PathAccess(current)
if index + 1 == num_args:
# read dict prop by path
value = path_dict.get(key)
@@ -174,6 +174,8 @@ def _process_ctx_request(ctx, args):
else:
raise RuntimeError('Illegal argument while accessing dict')
break
+ elif hasattr(current, '__getitem__') and (arg in current): # *must* be after MutableMapping
+ current = current[arg]
elif callable(current):
kwargs = {}
remaining_args = args[index:]
@@ -183,7 +185,7 @@ def _process_ctx_request(ctx, args):
current = current(*remaining_args, **kwargs)
break
else:
- raise RuntimeError('{0} cannot be processed in {1}'.format(arg, args))
+ raise RuntimeError('`{0}` cannot be processed in {1}'.format(arg, args))
index += 1
if callable(current):
current = current()
@@ -201,8 +203,8 @@ def _desugar_attr(obj, attr):
return None
-class _PathDictAccess(object):
- pattern = re.compile(r"(.+)\[(\d+)\]")
+class _PathAccess(object):
+ ARRAY_PATTERN = re.compile(r"(.+)\[(\d+)\]")
def __init__(self, obj):
self.obj = obj
@@ -216,26 +218,35 @@ class _PathDictAccess(object):
return value
def _get_object_by_path(self, prop_path, fail_on_missing=True):
- # when setting a nested object, make sure to also set all the
+ def has(name):
+ return (hasattr(current, '__iter__') and (name in current)) or hasattr(current, name)
+
+ def get(name):
+ if hasattr(current, '__iter__') and (name in current):
+ return current[name]
+ return getattr(current, name)
+
+ # When setting a nested object, make sure to also set all the
# intermediate path objects
current = self.obj
for prop_segment in prop_path.split('.'):
- match = self.pattern.match(prop_segment)
- if match:
- index = int(match.group(2))
- property_name = match.group(1)
- if property_name not in current:
+ array_match = _PathAccess.ARRAY_PATTERN.match(prop_segment)
+ if array_match:
+ index = int(array_match.group(2))
+ property_name = array_match.group(1)
+ if not has(property_name):
self._raise_illegal(prop_path)
if not isinstance(current[property_name], list):
self._raise_illegal(prop_path)
- current = current[property_name][index]
+ current = get(property_name)[index]
else:
- if prop_segment not in current:
+ if not has(prop_segment):
if fail_on_missing:
self._raise_illegal(prop_path)
else:
+ # TODO: won't this change the model???
current[prop_segment] = {}
- current = current[prop_segment]
+ current = get(prop_segment)
return current
def _get_parent_obj_prop_name_by_path(self, prop_path):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/storage/collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/aria/storage/collection_instrumentation.py b/aria/storage/collection_instrumentation.py
index c90cb18..dae884a 100644
--- a/aria/storage/collection_instrumentation.py
+++ b/aria/storage/collection_instrumentation.py
@@ -230,15 +230,20 @@ class _InstrumentedModel(_WrappedBase):
def _apply_instrumentation(self):
for field in self._instrumentation:
+ if field.parent.class_ != type(self._wrapped):
+ # Only apply fields of our class
+ continue
+
field_name = field.key
field_cls = field.mapper.class_
+
field = getattr(self._wrapped, field_name)
# Preserve the original value. e.g. original attributes would be located under
# _attributes
setattr(self, '_{0}'.format(field_name), field)
- # set instrumented value
+ # Set instrumented value
if isinstance(field, dict):
instrumentation_cls = _InstrumentedDict
elif isinstance(field, list):
@@ -247,7 +252,7 @@ class _InstrumentedModel(_WrappedBase):
# TODO: raise proper error
raise exceptions.StorageError(
"ARIA supports instrumentation for dict and list. Field {field} of the "
- "class {model} is of {type} type.".format(
+ "class `{model}` is of type `{type}`.".format(
field=field,
model=self._wrapped,
type=type(field)))
@@ -277,7 +282,7 @@ class _WrappedModel(_WrappedBase):
return _create_instrumented_model(
value, instrumentation=self._instrumentation, **self._kwargs)
elif hasattr(value, 'metadata') or isinstance(value, (dict, list)):
- # Basically checks that the value is indeed an sqlmodel (it should have metadata)
+ # Basically checks that the value is indeed a SQLAlchemy model (it should have metadata)
return _create_wrapped_model(
value, instrumentation=self._instrumentation, **self._kwargs)
return value
@@ -291,6 +296,10 @@ class _WrappedModel(_WrappedBase):
def __getitem__(self, item):
return self._wrap(self._wrapped[item])
+ def __iter__(self):
+ for item in self._wrapped.__iter__():
+ yield self._wrap(item)
+
def _create_instrumented_model(original_model, mapi, instrumentation):
return type('Instrumented{0}'.format(original_model.__class__.__name__),
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/aria/storage/core.py
----------------------------------------------------------------------
diff --git a/aria/storage/core.py b/aria/storage/core.py
index 2a5745e..527272c 100644
--- a/aria/storage/core.py
+++ b/aria/storage/core.py
@@ -130,7 +130,7 @@ class ModelStorage(Storage):
"""
model_name = model_cls.__modelname__
if model_name in self.registered:
- self.logger.debug('{name} in already storage {self!r}'.format(name=model_name,
+ self.logger.debug('{name} already in storage {self!r}'.format(name=model_name,
self=self))
return
self.registered[model_name] = self.api(name=model_name,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/clearwater-single-static.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/clearwater-single-static.yaml b/examples/clearwater/clearwater-single-static.yaml
new file mode 100644
index 0000000..82e1eda
--- /dev/null
+++ b/examples/clearwater/clearwater-single-static.yaml
@@ -0,0 +1,90 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: >-
+ Project Clearwater is an open-source IMS core, developed by Metaswitch Networks and released under
+ the GNU GPLv3.
+
+metadata:
+ template_name: clearwater-local
+ template_author: ARIA
+ template_version: '1.0.0'
+ aria_version: '0.1'
+
+imports:
+ - types/clearwater.yaml
+ - aria-1.0
+
+topology_template:
+
+ inputs:
+ hosts.ssh.user:
+ type: string
+ default: ubuntu
+ hosts.ssh.password:
+ type: string
+ default: ubuntu
+ static_host.public_address:
+ type: string
+ default: 192.168.1.170
+ static_host.private_address:
+ type: string
+ default: { get_input: static_host.public_address }
+
+ node_templates:
+ p-cscf:
+ type: clearwater.Bono
+
+ i-cscf:
+ type: clearwater.I-CSCF
+
+ s-cscf:
+ type: clearwater.S-CSCF
+
+ sip-as:
+ type: clearwater.Sprout
+
+ diameter:
+ type: clearwater.Dime
+
+ hss:
+ type: clearwater.Homestead
+
+ ctf:
+ type: clearwater.Ralf
+
+ state-store:
+ type: clearwater.Velum
+
+ xdms:
+ type: clearwater.Homer
+
+ frontend:
+ type: clearwater.Ellis
+ properties:
+ provision_numbers_count: 1000
+
+ static_host:
+ type: clearwater.Host
+ attributes:
+ public_address: { get_input: static_host.public_address }
+ private_address: { get_input: static_host.private_address }
+ capabilities:
+ host:
+ properties:
+ ssh.user: { get_input: hosts.ssh.user }
+ ssh.password: { get_input: hosts.ssh.password }
+ max_log_directory_size: 50 MiB
+ reduce_cassandra_mem_usage: true
+
+ smtp:
+ type: smtp.SMTP
+ capabilities:
+ smtp:
+ properties:
+ # TODO: not validating required :(
+ username: username
+ password: password
+
+ policies:
+ configuration:
+ type: clearwater.Configuration
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/bono/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/bono/create.sh b/examples/clearwater/scripts/bono/create.sh
new file mode 100644
index 0000000..6e441c2
--- /dev/null
+++ b/examples/clearwater/scripts/bono/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install bono restund
+yes | aptdcon --hide-terminal --install clearwater-management
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/bono/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/bono/delete.sh b/examples/clearwater/scripts/bono/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/dime/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/dime/create.sh b/examples/clearwater/scripts/dime/create.sh
new file mode 100644
index 0000000..584fcd0
--- /dev/null
+++ b/examples/clearwater/scripts/dime/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install dime clearwater-prov-tools
+yes | aptdcon --hide-terminal --install clearwater-management
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/dime/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/dime/delete.sh b/examples/clearwater/scripts/dime/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/ellis/configure.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ellis/configure.sh b/examples/clearwater/scripts/ellis/configure.sh
new file mode 100644
index 0000000..7ed387d
--- /dev/null
+++ b/examples/clearwater/scripts/ellis/configure.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -e
+
+PROVISION_NUMBERS_START=$(ctx node properties provision_numbers_start)
+PROVISION_NUMBERS_COUNT=$(ctx node properties provision_numbers_count)
+
+if [ "$PROVISION_NUMBERS_COUNT" != 0 ]; then
+ cd /usr/share/clearwater/ellis
+ . env/bin/activate
+ python src/metaswitch/ellis/tools/create_numbers.py \
+ --start "$PROVISION_NUMBERS_START" \
+ --count "$PROVISION_NUMBERS_COUNT"
+ deactivate
+fi
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/ellis/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ellis/create.sh b/examples/clearwater/scripts/ellis/create.sh
new file mode 100644
index 0000000..f7fb151
--- /dev/null
+++ b/examples/clearwater/scripts/ellis/create.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install ellis
+yes | aptdcon --hide-terminal --install clearwater-management
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/ellis/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ellis/delete.sh b/examples/clearwater/scripts/ellis/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/homer/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homer/create.sh b/examples/clearwater/scripts/homer/create.sh
new file mode 100644
index 0000000..c95cd2b
--- /dev/null
+++ b/examples/clearwater/scripts/homer/create.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install homer
+yes | aptdcon --hide-terminal --install clearwater-management
+
+# ARIA fix to avoid warnings by Twisted for missing service_identity library
+# (Crest is used by both Homer and Homestead-prov)
+cd /usr/share/clearwater/crest
+. env/bin/activate
+pip install service_identity
+deactivate
+service homer restart
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/homer/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homer/delete.sh b/examples/clearwater/scripts/homer/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/homestead/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homestead/create.sh b/examples/clearwater/scripts/homestead/create.sh
new file mode 100644
index 0000000..b130bd2
--- /dev/null
+++ b/examples/clearwater/scripts/homestead/create.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e
+
+# ARIA fix to avoid warnings by Twisted for missing service_identity library
+# (Crest is used by both Homer and Homestead-prov)
+cd /usr/share/clearwater/crest
+. env/bin/activate
+pip install service_identity
+deactivate
+service homer restart
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/homestead/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/homestead/delete.sh b/examples/clearwater/scripts/homestead/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/host/configure.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/host/configure.sh b/examples/clearwater/scripts/host/configure.sh
new file mode 100644
index 0000000..c661097
--- /dev/null
+++ b/examples/clearwater/scripts/host/configure.sh
@@ -0,0 +1,157 @@
+#!/bin/bash
+set -e
+
+# TODO: configure these in TOSCA -- via a policy?
+SITE_NAME=aria
+ZONE=example.com
+GEOGRAPHICALLY_REDUNDANT=False
+SECRET=secret
+
+# TODO: how to get these via ctx? ctx nodes smtp properties ...
+SMTP_HOSTNAME=127.0.0.1
+SMTP_USERNAME=username
+SMTP_PASSWORD=password
+
+MAX_LOG_DIRECTORY_SIZE=$(ctx node capabilities host properties max_log_directory_size.value)
+REDUCE_CASSANDRA_MEM_USAGE=$(ctx node capabilities host properties reduce_cassandra_mem_usage)
+
+PRIVATE_IP=$(ctx node attributes private_address)
+PUBLIC_IP=$(ctx node attributes public_address)
+PUBLIC_HOSTNAME=$(hostname)
+# TODO: comma-separated list of all private IP addresses in group
+ETCD_CLUSTER=$PRIVATE_IP
+
+REPO_FILE=/etc/apt/sources.list.d/clearwater.list
+REPO_LINE='deb http://repo.cw-ngv.com/stable binary/'
+KEY_URL=http://repo.cw-ngv.com/repo_key
+
+
+#
+# Repository
+#
+
+if [ ! -f "$REPO_FILE" ]; then
+ echo "$REPO_LINE" > "$REPO_FILE"
+ curl --location "$KEY_URL" | apt-key add -
+ apt update
+fi
+
+if ! type aptdcon > /dev/null; then
+ # This will allow us to do concurrent installs
+ apt install aptdaemon --yes
+fi
+
+
+#
+# DNS
+#
+
+S_CSCF_HOST="$PRIVATE_IP scscf.$HOSTNAME # ARIA"
+grep --quiet --fixed-strings "$S_CSCF_HOST" /etc/hosts || echo "$S_CSCF_HOST" >> /etc/hosts
+
+
+#
+# Local configuration
+#
+
+mkdir --parents /etc/clearwater
+CONFIG_FILE=/etc/clearwater/local_config
+echo "# Created by ARIA on $(date -u)" > "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Local IP configuration" >> "$CONFIG_FILE"
+echo "local_ip=$PRIVATE_IP" >> "$CONFIG_FILE"
+echo "public_ip=$PUBLIC_IP" >> "$CONFIG_FILE"
+echo "public_hostname=$PUBLIC_HOSTNAME" >> "$CONFIG_FILE"
+echo "etcd_cluster=$ETCD_CLUSTER" >> "$CONFIG_FILE"
+
+if [ "$MAX_LOG_DIRECTORY_SIZE" != 0 ]; then
+ echo >> "$CONFIG_FILE"
+ echo "max_log_directory_size=$MAX_LOG_DIRECTORY_SIZE" >> "$CONFIG_FILE"
+fi
+
+if [ "$GEOGRAPHICALLY_REDUNDANT" = True ]; then
+ echo >> "$CONFIG_FILE"
+ echo "# Geographically redundant" >> "$CONFIG_FILE"
+ echo "local_site_name=$SITE_NAME" >> "$CONFIG_FILE"
+
+ # On the first Vellum node in the second site, you should set remote_cassandra_seeds to the
+ # IP address of a Vellum node in the first site.
+ #echo "remote_cassandra_seeds=" >> "$CONFIG_FILE"
+fi
+
+
+#
+# Shared configuration
+#
+
+if [ "$GEOGRAPHICALLY_REDUNDANT" = True ]; then
+ SPROUT_HOSTNAME=sprout.$SITE_NAME.$ZONE
+ SPROUT_REGISTRATION_STORE=vellum.$SITE_NAME.$ZONE
+ HS_HOSTNAME=hs.$SITE_NAME.$ZONE:8888
+ HS_PROVISIONING_HOSTNAME=hs.$SITE_NAME.$ZONE:8889
+ RALF_HOSTNAME=ralf.$SITE_NAME.$ZONE:10888
+ RALF_SESSION_STORE=vellum.$ZONE
+ XDMS_HOSTNAME=homer.$SITE_NAME.$ZONE:7888
+ CHRONOS_HOSTNAME=vellum.$SITE_NAME.$ZONE
+ CASSANDRA_HOSTNAME=vellum.$SITE_NAME.$ZONE
+else
+ VELLUM_IP=$PRIVATE_IP
+ HOMESTEAD_IP=$PRIVATE_IP
+ HOMER_IP=$PRIVATE_IP
+
+ SPROUT_HOSTNAME=$PUBLIC_HOSTNAME
+ SPROUT_REGISTRATION_STORE=$VELLUM_IP
+ HS_HOSTNAME=$HOMESTEAD_IP:8888
+ HS_PROVISIONING_HOSTNAME=$HOMESTEAD_IP:8889
+ RALF_HOSTNAME=
+ RALF_SESSION_STORE=
+ XDMS_HOSTNAME=$HOMER_IP:7888
+ CHRONOS_HOSTNAME=
+ CASSANDRA_HOSTNAME=
+fi
+
+mkdir --parents /etc/clearwater
+CONFIG_FILE=/etc/clearwater/shared_config
+echo "# Created by ARIA on $(date -u)" > "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Deployment definitions" >> "$CONFIG_FILE"
+echo "home_domain=$ZONE" >> "$CONFIG_FILE"
+echo "sprout_hostname=$SPROUT_HOSTNAME" >> "$CONFIG_FILE"
+echo "sprout_registration_store=$SPROUT_REGISTRATION_STORE" >> "$CONFIG_FILE"
+echo "hs_hostname=$HS_HOSTNAME" >> "$CONFIG_FILE"
+echo "hs_provisioning_hostname=$HS_PROVISIONING_HOSTNAME" >> "$CONFIG_FILE"
+echo "ralf_hostname=$RALF_HOSTNAME" >> "$CONFIG_FILE"
+echo "ralf_session_store=$RALF_SESSION_STORE" >> "$CONFIG_FILE"
+echo "xdms_hostname=$XDMS_HOSTNAME" >> "$CONFIG_FILE"
+echo "chronos_hostname=$CHRONOS_HOSTNAME" >> "$CONFIG_FILE"
+echo "cassandra_hostname=$CASSANDRA_HOSTNAME" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Email server configuration" >> "$CONFIG_FILE"
+echo "smtp_smarthost=$SMTP_HOSTNAME" >> "$CONFIG_FILE"
+echo "smtp_username=$SMTP_USERNAME" >> "$CONFIG_FILE"
+echo "smtp_password=$SMTP_PASSWORD" >> "$CONFIG_FILE"
+echo "email_recovery_sender=clearwater@$ZONE" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# I-CSCF/S-CSCF configuration (used by Bono to proxy to Sprout)" >> "$CONFIG_FILE"
+echo "upstream_hostname=scscf.$HOSTNAME" >> "$CONFIG_FILE"
+
+echo >> "$CONFIG_FILE"
+echo "# Keys" >> "$CONFIG_FILE"
+echo "signup_key=$SECRET" >> "$CONFIG_FILE"
+echo "turn_workaround=$SECRET" >> "$CONFIG_FILE"
+echo "ellis_api_key=$SECRET" >> "$CONFIG_FILE"
+echo "ellis_cookie_key=$SECRET" >> "$CONFIG_FILE"
+
+if [ "$REDUCE_CASSANDRA_MEM_USAGE" = True ]; then
+ echo >> "$CONFIG_FILE"
+ echo "# $REDUCE_CASSANDRA_MEM_USAGE" >> "$CONFIG_FILE"
+ echo "reduce_cassandra_mem_usage=Y" >> "$CONFIG_FILE"
+fi
+
+# Copy to other hosts in etcd group
+#yes | aptdcon --hide-terminal --install clearwater-config-manager
+#cw-upload_shared_config
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/ralf/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ralf/create.sh b/examples/clearwater/scripts/ralf/create.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/ralf/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/ralf/delete.sh b/examples/clearwater/scripts/ralf/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/sprout/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/sprout/create.sh b/examples/clearwater/scripts/sprout/create.sh
new file mode 100644
index 0000000..904f002
--- /dev/null
+++ b/examples/clearwater/scripts/sprout/create.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install sprout
+yes | aptdcon --hide-terminal --install clearwater-management
+
+MEMENTO=$(ctx node properties memento)
+
+# Memento
+if [ "$MEMENTO" = True ]; then
+ yes | aptdcon --hide-terminal --install memento-as memento-nginx
+fi
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/sprout/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/sprout/delete.sh b/examples/clearwater/scripts/sprout/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/velum/create.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/velum/create.sh b/examples/clearwater/scripts/velum/create.sh
new file mode 100644
index 0000000..ae22417
--- /dev/null
+++ b/examples/clearwater/scripts/velum/create.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+set -e
+
+yes | aptdcon --hide-terminal --install vellum
+yes | aptdcon --hide-terminal --install clearwater-management
+
+# Memento
+#yes | aptdcon --hide-terminal --install memento-cassandra
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/scripts/velum/delete.sh
----------------------------------------------------------------------
diff --git a/examples/clearwater/scripts/velum/delete.sh b/examples/clearwater/scripts/velum/delete.sh
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/types/cassandra.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/cassandra.yaml b/examples/clearwater/types/cassandra.yaml
new file mode 100644
index 0000000..48ab4e9
--- /dev/null
+++ b/examples/clearwater/types/cassandra.yaml
@@ -0,0 +1,5 @@
+
+capability_types:
+
+ cassandra.Endpoint:
+ derived_from: tosca.capabilities.Endpoint.Database
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/types/clearwater.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/clearwater.yaml b/examples/clearwater/types/clearwater.yaml
new file mode 100644
index 0000000..0885721
--- /dev/null
+++ b/examples/clearwater/types/clearwater.yaml
@@ -0,0 +1,473 @@
+# http://clearwater.readthedocs.io/en/stable/Clearwater_Architecture.html
+
+imports:
+ - ims.yaml
+ - smtp.yaml
+ - cassandra.yaml
+
+dsl_definitions:
+
+ clearwater_operation_dependencies: &CLEARWATER_OPERATION_DEPENDENCIES
+ - "ssh.user > { get_property: [ HOST, host, ssh.user ] }"
+ - "ssh.password > { get_property: [ HOST, host, ssh.password ] }"
+ - "ssh.address > { get_attribute: [ HOST, public_address ] }"
+ - "ssh.use_sudo > true"
+
+policy_types:
+
+ clearwater.Configuration:
+ derived_from: tosca.policies.Root
+ properties:
+ site_name:
+ type: string
+ default: aria
+ zone:
+ type: string
+ default: example.com
+ geographically_redundant:
+ type: boolean
+ default: false
+ secret:
+ type: string
+ default: string
+
+capability_types:
+
+ clearwater.Container:
+ description: >-
+ Clearwater container capability.
+ derived_from: tosca.capabilities.Container
+ properties:
+ ssh.user:
+ type: string
+ ssh.password:
+ type: string
+ max_log_directory_size:
+ type: scalar-unit.size
+ default: 0 B # 0 means no max size
+ reduce_cassandra_mem_usage:
+ type: boolean
+ default: false
+
+ clearwater.Endpoint.SIP:
+ derived_from: ims.interfaces.SIP
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 5060
+
+ clearwater.Endpoint.SIP.Secure:
+ derived_from: ims.interfaces.SIP
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 5061
+
+ clearwater.Endpoint.SIP:
+ derived_from: ims.interfaces.SIP
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 5060
+
+ clearwater.Endpoint.HSS:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 8888
+
+ clearwater.Endpoint.HSS.Provisioning:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 8889
+
+ clearwater.Endpoint.CTF:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 10888
+
+ clearwater.Endpoint.Chronos:
+ derived_from: tosca.capabilities.Endpoint
+
+ clearwater.Endpoint.XDMS:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 7888
+
+ clearwater.Endpoint.Ellis:
+ derived_from: tosca.capabilities.Endpoint.Public
+ properties:
+ protocol: # override
+ type: string
+ default: http
+ port: # override
+ type: tosca.datatypes.network.PortDef
+ default: 80
+ url_path: # override
+ type: string
+ default: /
+
+data_types:
+
+ clearwater.Number:
+ derived_from: string
+ constraints:
+ - pattern: '^\d{10}$'
+
+node_types:
+
+ clearwater.SoftwareComponent:
+ description: >-
+ Clearwater software components must be installed in a Clearwater-capable compute node.
+ derived_from: tosca.nodes.SoftwareComponent
+ requirements:
+ - host: # override
+ capability: clearwater.Container
+ node: tosca.nodes.Compute # TODO: we shouldn't need this, see comment in ARIA-174
+ relationship: tosca.relationships.HostedOn
+
+ clearwater.Bono:
+ description: >-
+ Clearwater edge proxy.
+
+ The Bono nodes form a horizontally scalable SIP edge proxy providing both a SIP IMS Gm
+ compliant interface and a WebRTC interface to clients. Client connections are load balanced
+ across the nodes. The Bono node provides the anchor point for the client's connection to the
+ Clearwater system, including support for various NAT traversal mechanisms. A client is
+ therefore anchored to a particular Bono node for the duration of its registration, but can
+ move to another Bono node if the connection or client fails.
+
+ Clients can connect to Bono using SIP/UDP or SIP/TCP. Bono supports any WebRTC client that
+ performs call setup signaling using SIP over WebSocket.
+
+ Alternatively, Clearwater can be deployed with a third party P-CSCF or Session Border
+ Controller implementing P-CSCF. In this case Bono nodes are not required.
+ derived_from: clearwater.SoftwareComponent
+ capabilities:
+ p-cscf: ims.functions.P-CSCF
+ sip_endpoint: clearwater.Endpoint.SIP
+ sip_secure_endpoint: clearwater.Endpoint.SIP.Secure
+ gm: ims.interfaces.Gm
+ requirements:
+ - sip_as:
+ capability: ims.functions.SIP-AS
+ node: tosca.nodes.Root # TODO: we shouldn't need this, see comment in ARIA-174
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/bono/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/bono/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.I-CSCF:
+ description: >-
+ Logical node.
+ derived_from: tosca.nodes.Root
+ capabilities:
+ i-cscf: ims.functions.I-CSCF
+ requirements:
+ - sprout:
+ capability: tosca.capabilities.Node
+ node: clearwater.Sprout
+ - homsetead:
+ capability: tosca.capabilities.Node
+ node: clearwater.Homestead
+
+ clearwater.S-CSCF:
+ description: >-
+ Logical node.
+ derived_from: tosca.nodes.Root
+ capabilities:
+ s-cscf: ims.functions.S-CSCF
+ requirements:
+ - sprout:
+ capability: tosca.capabilities.Node
+ node: clearwater.Sprout
+ - homsetead:
+ capability: tosca.capabilities.Node
+ node: clearwater.Homestead
+
+ clearwater.Sprout:
+ description: >-
+ Clearwater SIP router.
+
+ The Sprout nodes act as a horizontally scalable, combined SIP registrar and authoritative
+ routing proxy, and handle client authentication and the ISC interface to application servers.
+ The Sprout nodes also contain the in-built MMTEL application server. SIP transactions are load
+ balanced across the Sprout cluster, so there is no long-lived association between a client and
+ a particular Sprout node. Sprout does not store any long-lived data itself and instead uses
+ web service interfaces to Homestead and Homer to retrieve HSS configuration such as
+ authentication data/user profiles and MMTEL service settings APIs to Vellum for storing
+ subscriber registration data and for running timers.
+
+ Sprout is where the bulk of the I-CSCF and S-CSCF function resides, with the remainder
+ provided by Dime (and backed by the long-lived data stores on Vellum).
+ derived_from: clearwater.SoftwareComponent
+ capabilities:
+ sip-as: ims.functions.SIP-AS
+ sip_endpoint: clearwater.Endpoint.SIP
+ sip_secure_endpoint: clearwater.Endpoint.SIP.Secure
+ properties:
+ memento:
+ description: >-
+ Set to true if you want the Sprout node to include a Memento Application server.
+ type: boolean
+ default: false
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/sprout/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/sprout/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Dime:
+ description: >-
+ Clearwater Diameter gateway.
+
+ Dime nodes run Clearwater's Homestead and Ralf components.
+ derived_from: clearwater.SoftwareComponent
+ capabilities:
+ host:
+ type: tosca.capabilities.Container
+ valid_source_types: [ clearwater.DimeSoftwareComponent ]
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/dime/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/dime/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.DimeSoftwareComponent:
+ description: >-
+ Base type for Dime software components.
+ derived_from: clearwater.SoftwareComponent
+ requirements:
+ - host: # override
+ capability: tosca.capabilities.Container
+ node: clearwater.Dime
+
+ clearwater.Homestead:
+ description: >-
+ Clearwater HSS cache.
+
+ Homestead provides a web services interface to Sprout for retrieving authentication
+ credentials and user profile information. It can either master the data (in which case it
+ exposes a web services provisioning interface) or can pull the data from an IMS compliant HSS
+ over the Cx interface. The Homestead nodes themselves are stateless - the mastered / cached
+ subscriber data is all stored on Vellum (via Cassandra’s Thrift interface).
+
+ In the IMS architecture, the HSS mirror function is considered to be part of the I-CSCF and
+ S-CSCF components, so in Clearwater I-CSCF and S-CSCF function is implemented with a
+ combination of Sprout and Dime clusters.
+ derived_from: clearwater.DimeSoftwareComponent
+ capabilities:
+ hss: ims.functions.HSS
+ cx: ims.interfaces.Cx
+ hss_endpoint: clearwater.Endpoint.HSS
+ hss_provisioning_endpoint: clearwater.Endpoint.HSS.Provisioning
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/homestead/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/homestead/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Ralf:
+ description: >-
+ Clearwater CTF.
+
+ Ralf provides an HTTP API that both Bono and Sprout can use to report billable events that
+ should be passed to the CDF (Charging Data Function) over the Rf billing interface. Ralf is
+ stateless, using Vellum to maintain the long lived session state and run the timers necessary
+ to enable it to conform to the Rf protocol.
+ derived_from: clearwater.DimeSoftwareComponent
+ capabilities:
+ rf: ims.interfaces.Rf
+ ctf_endpoint: clearwater.Endpoint.CTF
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/ralf/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/ralf/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Velum:
+ description: >-
+ Clearwater state store.
+
+ Vellum is used to maintain all long-lived state in the deployment. It does this by running a
+ number of cloud optimized, distributed storage clusters.
+
+ - Cassandra. Cassandra is used by Homestead to store authentication credentials and profile
+ information, and is used by Homer to store MMTEL service settings. Vellum exposes Cassandra's
+ Thrift API.
+
+ - etcd. etcd is used by Vellum itself to share clustering information between Vellum nodes and
+ by other nodes in the deployment for shared configuration.
+
+ - Chronos. Chronos is a distributed, redundant, reliable timer service developed by
+ Clearwater. It is used by Sprout and Ralf nodes to enable timers to be run (e.g. for SIP
+ Registration expiry) without pinning operations to a specific node (one node can set the timer
+ and another act on it when it pops). Chronos is accessed via an HTTP API.
+
+ - Memcached / Astaire. Vellum also runs a Memcached cluster fronted by Astaire. Astaire is a
+ service developed by Clearwater that enabled more rapid scale up and scale down of memcached
+ clusters. This cluster is used by Sprout and Ralf for storing registration and session state.
+ derived_from: clearwater.SoftwareComponent
+ capabilities:
+ cassandra_endpoint: cassandra.Endpoint
+ chronos_endpoint: clearwater.Endpoint.Chronos
+ properties:
+ memento:
+ description: >-
+ Set to true if you want your Sprout node includes a Memento Application server.
+ type: boolean
+ default: false
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/velum/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/velum/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Homer:
+ description: >-
+ Clearwater XDMS.
+
+ Homer is a standard XDMS used to store MMTEL service settings documents for each user of the
+ system. Documents are created, read, updated and deleted using a standard XCAP interface. As
+ with Homestead, the Homer nodes use Vellum as the data store for all long lived data.
+ derived_from: clearwater.SoftwareComponent
+ capabilities:
+ xdms_endpoint: clearwater.Endpoint.XDMS
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/homer/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/homer/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Ellis:
+ description: >-
+ Ellis is a sample provisioning portal providing self sign-up, password management, line
+ management and control of MMTEL service settings. It is not intended to be a part of
+ production Clearwater deployments (it is not easy to horizontally scale because of the MySQL
+ underpinnings for one thing) but to make the system easy to use out of the box.
+ derived_from: clearwater.SoftwareComponent
+ properties:
+ provision_numbers_start:
+ type: clearwater.Number
+ default: '6505550000'
+ provision_numbers_count:
+ type: integer
+ default: 0 # 0 means do not provision numbers
+ constraints:
+ - greater_or_equal: 0
+ capabilities:
+ web_endpoint: clearwater.Endpoint.Ellis
+ requirements:
+ - xdms:
+ capability: clearwater.Endpoint.XDMS
+ node: tosca.nodes.Root # TODO: we shouldn't need this, see comment in ARIA-174
+ - hss:
+ capability: clearwater.Endpoint.HSS
+ node: tosca.nodes.Root # TODO: we shouldn't need this, see comment in ARIA-174
+ - hss_provisioning:
+ capability: clearwater.Endpoint.HSS.Provisioning
+ node: tosca.nodes.Root # TODO: we shouldn't need this, see comment in ARIA-174
+ - ctf:
+ capability: clearwater.Endpoint.CTF
+ node: tosca.nodes.Root # TODO: we shouldn't need this, see comment in ARIA-174
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ create:
+ implementation:
+ primary: scripts/ellis/create.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ configure:
+ implementation:
+ primary: scripts/ellis/configure.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ delete:
+ implementation:
+ primary: scripts/ellis/delete.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+
+ clearwater.Host:
+ description: >-
+ Default Clearwater host.
+
+ Note that any node can function as a Clearwater host as long as it has a clearwater.Container
+ capability.
+ derived_from: tosca.nodes.Compute
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ configure:
+ implementation:
+ primary: scripts/host/configure.sh
+ dependencies: *CLEARWATER_OPERATION_DEPENDENCIES
+ capabilities:
+ host: # override
+ type: clearwater.Container
+ valid_source_types: [ tosca.nodes.SoftwareComponent ]
+ os: # override
+ type: tosca.capabilities.OperatingSystem
+ properties:
+ architecture:
+ type: string
+ default: x86_64
+ type:
+ type: string
+ default: linux
+ distribution:
+ type: string
+ default: ubuntu
+ version:
+ type: version
+ default: 14.04
+ smtp:
+ type: smtp.SMTP
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/types/ims.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/ims.yaml b/examples/clearwater/types/ims.yaml
new file mode 100644
index 0000000..41d1eb5
--- /dev/null
+++ b/examples/clearwater/types/ims.yaml
@@ -0,0 +1,413 @@
+# https://en.wikipedia.org/wiki/IP_Multimedia_Subsystem#Interfaces_description
+
+capability_types:
+
+ # In IMS these are called "interfaces".
+
+ ims.interfaces.Diameter:
+ derived_from: tosca.capabilities.Endpoint
+
+ ims.interfaces.TCP:
+ derived_from: tosca.capabilities.Endpoint
+
+ ims.interfaces.SIP:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ protocol: # override
+ type: string
+ default: sip
+
+ ims.interfaces.RTP:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ protocol: # override
+ type: string
+ default: rtp
+
+ ims.interfaces.H248:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ protocol: # override
+ type: string
+ default: h248
+
+ ims.interfaces.HTTP:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ protocol: # override
+ type: string
+ default: http
+
+ ims.interfaces.MAP:
+ derived_from: tosca.capabilities.Endpoint
+ properties:
+ protocol: # override
+ type: string
+ default: map
+
+ ims.interfaces.Cr:
+ description: >-
+ Used by MRFC to fetch documents (e.g. scripts, announcement files, and other resources) from
+ an AS. Also used for media control related commands.
+ derived_from: ims.interfaces.TCP
+
+ ims.interfaces.Cx:
+ description: >-
+ Used to send subscriber data to the S-CSCF; including filter criteria and their priority. Also
+ used to furnish CDF and/or OCF addresses.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Dh:
+ description: >-
+ Used by AS to find the HSS holding the user profile information in a multi-HSS environment.
+ DH_SLF_QUERY indicates an IMPU and DX_SLF_RESP return the HSS name.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Dx:
+ description: >-
+ Used by I-CSCF or S-CSCF to find a correct HSS in a multi-HSS environment. DX_SLF_QUERY
+ indicates an IMPU and DX_SLF_RESP return the HSS name.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Gm:
+ description: >-
+ Used to exchange messages between SIP user equipment (UE) or Voip gateway and P-CSCF.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Go:
+ description: >-
+ Allows operators to control QoS in a user plane and exchange charging correlation
+ information between IMS and GPRS network.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Gq:
+ description: >-
+ Used to exchange policy decisions-related information between P-CSCF and PDF.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Gx:
+ description: >-
+ Used to exchange policy decisions-related information between PCEF and PCRF.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Gy:
+ description: >-
+ Used for online flow-based bearer charging. Functionally equivalent to Ro interface.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.ISC:
+ description: >-
+ Reference point between S-CSCF and AS. Main functions are to:
+ * Notify the AS of the registered IMPU, registration state and UE capabilities
+ * Supply the AS with information to allow it to execute multiple services
+ * Convey charging function addresses
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Ici:
+ description: >-
+ Used to exchange messages between an IBCF and another IBCF belonging to a different IMS
+ network.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Izi:
+ description: >-
+ Used to forward media streams from a TrGW to another TrGW belonging to a different IMS
+ network.
+ derived_from: ims.interfaces.RTP
+
+ ims.interfaces.Ma:
+ description: >-
+ Main functions are to:
+ * Forward SIP requests which are destined to a public service identity hosted by the AS
+ * Originate a session on behalf of a user or public service identity, if the AS has no
+ knowledge of a S-CSCF assigned to that user or public service identity
+ * Convey charging function addresses
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mg:
+ description: >-
+ ISUP signalling to SIP signalling and forwards SIP signalling to I-CSCF.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mi:
+ description: >-
+ Used to exchange messages between S-CSCF and BGCF.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mj:
+ description: >-
+ Used for the interworking with the PSTN/CS domain, when the BGCF has determined that a
+ breakout should occur in the same IMS network to send SIP message from BGCF to MGCF.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mk:
+ description: >-
+ Used for the interworking with the PSTN/CS domain, when the BGCF has determined that a
+ breakout should occur in another IMS network to send SIP message from BGCF to the BGCF in the
+ other network.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mm:
+ description: >-
+ Used for exchanging messages between IMS and external IP networks.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mn:
+ description: >-
+ Allows control of user-plane resources.
+ derived_from: ims.interfaces.H248
+
+ ims.interfaces.Mp:
+ description: >-
+ Allows an MRFC to control media stream resources provided by an MRFP.
+ derived_from: ims.interfaces.H248
+
+ ims.interfaces.Mr:
+ description: >-
+ Used to exchange information between S-CSCF and MRFC.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mr2:
+ description: >-
+ Used to exchange session controls between AS and MRFC.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mw:
+ description: >-
+ Used to exchange messages between CSCFs. AGCF appears as a P-CSCF to the other CSCFs.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Mx:
+ description: >-
+ Used for the interworking with another IMS network, when the BGCF has determined that a
+ breakout should occur in the other IMS network to send SIP message from BGCF to the IBCF in
+ the other network.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.P1:
+ description: >-
+ Used for call control services by AGCF to control H.248 A-MGW and residential gateways.
+ derived_from: ims.interfaces.H248
+
+ ims.interfaces.P2:
+ description: >-
+ Reference point between AGCF and CSCF.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Rc:
+ description: >-
+ Used by the AS to request that media resources be assigned to a call when using MRB in-line
+ mode or in query mode.
+ derived_from: ims.interfaces.SIP
+
+ ims.interfaces.Rf:
+ description: >-
+ Used to exchange offline charging information with CDF.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Ro:
+ description: >-
+ Used to exchange online charging information with OCF.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Rx:
+ description: >-
+ Used to exchange policy and charging related information between P-CSCF and PCRF. Replacement
+ for the Gq reference point.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Sh:
+ description: >-
+ Used to exchange User Profile information (e.g., user-related data, group lists,
+ user-service-related information or user location information or charging function addresses
+ (used when the AS has not received the third-party REGISTER for a user)) between an AS (SIP
+ AS or OSA SCS) and HSS. Also allow AS to activate/deactivate filter criteria stored in the HSS
+ on a per-subscriber basis.
+ derived_from: ims.interfaces.Diameter
+
+ ims.interfaces.Si:
+ description: >-
+ Transports CAMEL subscription information, including triggers for use by CAMEL-based
+ application services information.
+ derived_from: ims.interfaces.MAP
+
+ ims.interfaces.Sr:
+ description: >-
+ Used by MRFC to fetch documents (scripts and other resources) from an AS.
+ derived_from: ims.interfaces.HTTP
+
+ ims.interfaces.Ut:
+ description: >-
+ Facilitates the management of subscriber information related to services and settings.
+ derived_from: ims.interfaces.HTTP
+
+ ims.interfaces.Z:
+ description: >-
+ Conversion of POTS services to SIP messages.
+ derived_from: tosca.capabilities.Root
+
+
+# https://en.wikipedia.org/wiki/IP_Multimedia_Subsystem#Core_network
+
+ ims.functions.Root:
+ derived_from: tosca.capabilities.Root
+
+ ims.functions.HSS:
+ description: >-
+ The home subscriber server (HSS), or user profile server function (UPSF), is a master user
+ database that supports the IMS network entities that actually handle calls. It contains the
+ subscription-related information (subscriber profiles), performs authentication and
+ authorization of the user, and can provide information about the subscriber's location and IP
+ information. It is similar to the GSM home location register (HLR) and Authentication centre
+ (AuC).
+
+ A subscriber location function (SLF) is needed to map user addresses when multiple HSSs are
+ used.
+ derived_from: ims.functions.Root
+
+ ims.functions.CSCF:
+ description: >-
+ Several roles of SIP servers or proxies, collectively called Call Session Control Function
+ (CSCF), are used to process SIP signalling packets in the IMS.
+ derived_from: ims.functions.Root
+
+ ims.functions.P-CSCF:
+ description: >-
+ A Proxy-CSCF (P-CSCF) is a SIP proxy that is the first point of contact for the IMS terminal.
+ It can be located either in the visited network (in full IMS networks) or in the home network
+ (when the visited network is not IMS compliant yet). Some networks may use a Session Border
+ Controller (SBC) for this function. The P-CSCF is at its core a specialized SBC for the
+ User–network interface which not only protects the network, but also the IMS terminal. The use
+ of an additional SBC between the IMS terminal and the P-CSCF is unnecessary and infeasible due
+ to the signaling being encrypted on this leg. The terminal discovers its P-CSCF with either
+ DHCP, or it may be configured (e.g. during initial provisioning or via a 3GPP IMS Management
+ Object (MO)) or in the ISIM or assigned in the PDP Context (in General Packet Radio Service
+ (GPRS)).
+ derived_from: ims.functions.CSCF
+
+ ims.functions.I-CSCF:
+ description: >-
+ An Interrogating-CSCF (I-CSCF) is another SIP function located at the edge of an
+ administrative domain. Its IP address is published in the Domain Name System (DNS) of the
+ domain (using NAPTR and SRV type of DNS records), so that remote servers can find it, and use
+ it as a forwarding point (e.g., registering) for SIP packets to this domain.
+ derived_from: ims.functions.CSCF
+
+ ims.functions.S-CSCF:
+ description: >-
+ A Serving-CSCF (S-CSCF) is the central node of the signalling plane. It is a SIP server, but
+ performs session control too. It is always located in the home network. It uses Diameter Cx
+ and Dx interfaces to the HSS to download user profiles and upload user-to-S-CSCF associations
+ (the user profile is only cached locally for processing reasons only and is not changed). All
+ necessary subscriber profile information is loaded from the HSS.
+ derived_from: ims.functions.CSCF
+
+ ims.functions.AS:
+ description: >-
+ SIP Application servers (AS) host and execute services, and interface with the S-CSCF using
+ SIP. An example of an application server that is being developed in 3GPP is the Voice call
+ continuity Function (VCC Server). Depending on the actual service, the AS can operate in SIP
+ proxy mode, SIP UA (user agent) mode or SIP B2BUA mode. An AS can be located in the home
+ network or in an external third-party network. If located in the home network, it can query
+ the HSS with the Diameter Sh or Si interfaces (for a SIP-AS).
+ derived_from: ims.functions.Root
+
+ ims.functions.SIP-AS:
+ description: >-
+ Host and execute IMS specific services.
+ derived_from: ims.functions.AS
+
+ ims.functions.IM-SSF:
+ description: >-
+ IP Multimedia Service Switching Function. Interfaces SIP to CAP to communicate with CAMEL
+ Application Servers.
+ derived_from: ims.functions.AS
+
+ ims.functions.OSA-SCS:
+ description: >-
+ OSA service capability server. Interfaces SIP to the OSA framework.
+ derived_from: ims.functions.AS
+
+ ims.functions.AS-ILCM:
+ description: >-
+ The AS-ILCM (Application Server - Incoming Leg Control Model) stores transaction state, and
+ may optionally store session state depending on the specific service being executed. The
+ AS-ILCM interfaces to the S-CSCF (ILCM) for an incoming leg. Application Logic provides the
+ service(s) and interacts between the AS-ILCM and AS-OLCM.
+ derived_from: ims.functions.AS
+
+ ims.functions.AS-OLCM:
+ description: >-
+ The AS-OLCM (Application Server - Outgoing Leg Control Model) stores transaction state, and
+ may optionally store session state depending on the specific service being executed. The
+ AS-OLCM interfaces to the S-CSCF (OLCM) for an outgoing leg. Application Logic provides the
+ service(s) and interacts between the AS-ILCM and AS-OLCM.
+ derived_from: ims.functions.AS
+
+ ims.functions.MRF:
+ description: >-
+ The Media Resource Function (MRF) provides media related functions such as media manipulation
+ (e.g. voice stream mixing) and playing of tones and announcements.
+
+ Each MRF is further divided into a media resource function controller (MRFC) and a media
+ resource function processor (MRFP).
+ derived_from: ims.functions.Root
+
+ ims.functions.MRFC:
+ description: >-
+ The MRFC is a signalling plane node that interprets information coming from an AS and S-CSCF
+ to control the MRFP.
+ derived_from: ims.functions.Root
+
+ ims.functions.MRFP:
+ description: >-
+ The MRFP is a media plane node used to mix, source or process media streams. It can also
+ manage access right to shared resources.
+ derived_from: ims.functions.Root
+
+ ims.functions.MRB:
+ description: >-
+ The Media Resource Broker (MRB) is a functional entity that is responsible for both collection
+ of appropriate published MRF information and supplying of appropriate MRF information to
+ consuming entities such as the AS. MRB can be used in two modes:
+ * Query mode: AS queries the MRB for media and sets up the call using the response of MRB
+ * In-Line Mode: AS sends a SIP INVITE to the MRB. The MRB sets up the call
+ derived_from: ims.functions.Root
+
+ ims.functions.BGCF:
+ description: >-
+ A Breakout Gateway Control Function (BGCF) is a SIP proxy which processes requests for routing
+ from an S-CSCF when the S-CSCF has determined that the session cannot be routed using DNS or
+ ENUM/DNS. It includes routing functionality based on telephone numbers.
+ derived_from: ims.functions.Root
+
+ ims.functions.PTSNGateway:
+ description: >-
+ A PSTN/CS gateway interfaces with PSTN circuit switched (CS) networks. For signalling, CS
+ networks use ISDN User Part (ISUP) (or BICC) over Message Transfer Part (MTP), while IMS uses
+ SIP over IP. For media, CS networks use Pulse-code modulation (PCM), while IMS uses Real-time
+ Transport Protocol (RTP).
+ derived_from: ims.functions.Root
+
+ ims.functions.SGW:
+ description: >-
+ A signalling gateway (SGW) interfaces with the signalling plane of the CS. It transforms lower
+ layer protocols as Stream Control Transmission Protocol (SCTP, an IP protocol) into Message
+ Transfer Part (MTP, an Signalling System 7 (SS7) protocol), to pass ISDN User Part (ISUP) from
+ the MGCF to the CS network.
+ derived_from: ims.functions.PTSNGateway
+
+ ims.functions.MGCF:
+ description: >-
+ A media gateway controller function (MGCF) is a SIP endpoint that does call control protocol
+ conversion between SIP and ISUP/BICC and interfaces with the SGW over SCTP. It also controls
+ the resources in a Media Gateway (MGW) across an H.248 interface.
+ derived_from: ims.functions.PTSNGateway
+
+ ims.functions.MGW:
+ description: >-
+ A media gateway (MGW) interfaces with the media plane of the CS network, by converting between
+ RTP and PCM. It can also transcode when the codecs don't match (e.g., IMS might use AMR, PSTN
+ might use G.711).
+ derived_from: ims.functions.PTSNGateway
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/clearwater/types/smtp.yaml
----------------------------------------------------------------------
diff --git a/examples/clearwater/types/smtp.yaml b/examples/clearwater/types/smtp.yaml
new file mode 100644
index 0000000..9ca116e
--- /dev/null
+++ b/examples/clearwater/types/smtp.yaml
@@ -0,0 +1,18 @@
+
+capability_types:
+
+ smtp.SMTP:
+ derived_from: tosca.capabilities.Root
+ properties:
+ username:
+ type: string
+ password:
+ type: string
+
+node_types:
+
+ smtp.SMTP:
+ derived_from: tosca.nodes.SoftwareComponent
+ capabilities:
+ smtp:
+ type: smtp.SMTP
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/hello-world/hello-world.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/hello-world.yaml b/examples/hello-world/hello-world.yaml
new file mode 100644
index 0000000..86e2ad0
--- /dev/null
+++ b/examples/hello-world/hello-world.yaml
@@ -0,0 +1,38 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+node_types:
+
+ WebServer:
+ derived_from: tosca:Root
+ capabilities:
+ host:
+ type: tosca:Container
+
+ WebApp:
+ derived_from: tosca:WebApplication
+ properties:
+ port:
+ type: integer
+
+topology_template:
+
+ node_templates:
+ web_server:
+ type: WebServer
+
+ web_app:
+ type: WebApp
+ properties:
+ port: 9090
+ requirements:
+ - host: web_server
+ interfaces:
+ Standard:
+ configure: scripts/configure.sh
+ start: scripts/start.sh
+ stop: scripts/stop.sh
+
+ outputs:
+ port:
+ type: integer
+ value: { get_property: [ web_app, port ] }
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/examples/hello-world/helloworld.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/helloworld.yaml b/examples/hello-world/helloworld.yaml
deleted file mode 100644
index 2fdc4d4..0000000
--- a/examples/hello-world/helloworld.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-node_types:
-
- WebServer:
- derived_from: tosca:Root
- capabilities:
- host:
- type: tosca.capabilities.Container
-
- WebApp:
- derived_from: tosca.nodes.WebApplication
- properties:
- port:
- type: integer
-
-topology_template:
-
- node_templates:
- web_server:
- type: WebServer
-
- web_app:
- type: WebApp
- properties:
- port: 9090
- requirements:
- - host: web_server
- interfaces:
- Standard:
- configure: scripts/configure.sh
- start: scripts/start.sh
- stop: scripts/stop.sh
-
- outputs:
- port:
- type: integer
- value: { get_property: [ web_app, port ] }
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
index 513b517..216f1e4 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
@@ -163,7 +163,7 @@ class Version(object):
#TYPE_TOSCA_VERSION>`__
"""
- REGULAR = \
+ REGEX = \
r'^(?P<major>\d+)\.(?P<minor>\d+)(\.(?P<fix>\d+)' + \
r'((\.(?P<qualifier>\d+))(\-(?P<build>\d+))?)?)?$'
@@ -176,7 +176,7 @@ class Version(object):
def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
str_value = str(value)
- match = re.match(Version.REGULAR, str_value)
+ match = re.match(Version.REGEX, str_value)
if match is None:
raise ValueError(
'version must be formatted as <major_version>.<minor_version>'
@@ -376,11 +376,14 @@ class Scalar(object):
def __init__(self, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
str_value = str(value)
- match = re.match(self.REGULAR, str_value) # pylint: disable=no-member
+ match = re.match(self.REGEX, str_value) # pylint: disable=no-member
if match is None:
raise ValueError('scalar must be formatted as <scalar> <unit>: %s' % safe_repr(value))
self.factor = float(match.group('scalar'))
+ if self.factor < 0:
+ raise ValueError('scalar is negative: %s' % safe_repr(self.factor))
+
self.unit = match.group('unit')
unit_lower = self.unit.lower()
@@ -435,7 +438,7 @@ class ScalarSize(Scalar):
"""
# See: http://www.regular-expressions.info/floatingpoint.html
- REGULAR = \
+ REGEX = \
r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>B|kB|KiB|MB|MiB|GB|GiB|TB|TiB)$'
UNITS = {
@@ -464,7 +467,7 @@ class ScalarTime(Scalar):
"""
# See: http://www.regular-expressions.info/floatingpoint.html
- REGULAR = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>ns|us|ms|s|m|h|d)$'
+ REGEX = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>ns|us|ms|s|m|h|d)$'
UNITS = {
'ns': 0.000000001,
@@ -490,7 +493,7 @@ class ScalarFrequency(Scalar):
"""
# See: http://www.regular-expressions.info/floatingpoint.html
- REGULAR = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>Hz|kHz|MHz|GHz)$'
+ REGEX = r'^(?P<scalar>[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)\s*(?P<unit>Hz|kHz|MHz|GHz)$'
UNITS = {
'Hz': 1.0,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index 5427c7e..1b95bec 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -68,12 +68,14 @@ def get_inherited_capability_definitions(context, presentation, for_presentation
capability_definition = capability_definitions[capability_name]
# Check if we changed the type
- type1 = capability_definition.type
- type2 = our_capability_definition.type
- if type1 != type2:
+ type1 = capability_definition._get_type(context)
+ type2 = our_capability_definition._get_type(context)
+
+ if not type1._is_descendant(context, type2):
context.validation.report(
- 'capability definition changes type from "{0}" to "{1}" in "{2}"'
- .format(type1, type2, presentation._fullname),
+ 'capability definition type "{0}" is not a descendant of overridden '
+ 'capability definition type "{1}"' \
+ .format(type1._name, type2._name),
locator=our_capability_definition._locator, level=Issue.BETWEEN_TYPES)
merge_capability_definition(context, presentation, capability_definition,
@@ -168,6 +170,8 @@ def merge_capability_definition(context, presentation, capability_definition,
from_capability_definition):
raw_properties = OrderedDict()
+ capability_definition._raw['type'] = from_capability_definition.type
+
# Merge properties from type
from_property_defintions = from_capability_definition.properties
merge_raw_parameter_definitions(context, presentation, raw_properties, from_property_defintions,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
index fbb8280..5bdbb43 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -159,10 +159,6 @@ def get_data_type(context, presentation, field_name, allow_none=False):
else:
return str
- # Make sure not derived from self
- if type_name == presentation._name:
- return None
-
# Avoid circular definitions
container_data_type = get_container_data_type(presentation)
if (container_data_type is not None) and (container_data_type._name == type_name):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
index 590c6a0..ecbfde9 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
@@ -200,20 +200,24 @@ class GetProperty(Function):
for modelable_entity in modelable_entities:
properties = None
+ # First argument refers to a requirement template?
if hasattr(modelable_entity, 'requirement_templates') \
and modelable_entity.requirement_templates \
and (req_or_cap_name in [v.name for v in modelable_entity.requirement_templates]):
- for requirement_template in modelable_entity.requirement_templates:
- if requirement_template.name == req_or_cap_name:
- # First argument refers to a requirement
- # TODO: should follow to matched capability in other node...
+ for requirement in modelable_entity.requirement_templates:
+ if requirement.name == req_or_cap_name:
+ # TODO
raise CannotEvaluateFunctionException()
- # break
+ # First argument refers to a capability?
+ elif hasattr(modelable_entity, 'capabilities') \
+ and modelable_entity.capabilities \
+ and (req_or_cap_name in modelable_entity.capabilities):
+ properties = modelable_entity.capabilities[req_or_cap_name].properties
nested_property_name_or_index = self.nested_property_name_or_index[1:]
+ # First argument refers to a capability template?
elif hasattr(modelable_entity, 'capability_templates') \
and modelable_entity.capability_templates \
and (req_or_cap_name in modelable_entity.capability_templates):
- # First argument refers to a capability
properties = modelable_entity.capability_templates[req_or_cap_name].properties
nested_property_name_or_index = self.nested_property_name_or_index[1:]
else:
@@ -640,7 +644,7 @@ def get_target(container_holder, name, locator):
def get_modelable_entity_parameter(modelable_entity, parameters, nested_parameter_name_or_index):
if not parameters:
- return False, True, None
+ return Evaluation(None, True)
found = True
final = True
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
index d5f447c..d41aa81 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -400,13 +400,15 @@ def merge_raw_operation_definitions(context, raw_operations, our_operations, int
def merge_interface_definition(context, interface, our_source, presentation, type_name):
if hasattr(our_source, 'type'):
# Check if we changed the interface type
- input_type1 = interface.type
- input_type2 = our_source.type
- if (input_type1 is not None) and (input_type2 is not None) and (input_type1 != input_type2):
+ type1 = interface._get_type(context)
+ type2 = our_source._get_type(context)
+
+ if (type2 is not None) and not type1._is_descendant(context, type2):
context.validation.report(
- 'interface definition "%s" changes type from "%s" to "%s" in "%s"'
- % (interface._name, input_type1, input_type2, presentation._fullname),
- locator=input_type2._locator, level=Issue.BETWEEN_TYPES)
+ 'interface definition type "{0}" is not a descendant of overridden '
+ 'interface definition type "{1}"' \
+ .format(type1._name, type2._name),
+ locator=our_source._locator, level=Issue.BETWEEN_TYPES)
# Add/merge inputs
our_interface_inputs = our_source._get_inputs(context) \
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
index 87c1a3b..bc884e2 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
@@ -18,7 +18,8 @@ from aria.utils.formatting import pluralize
from aria.parser.presentation import Value
from aria.parser.validation import Issue
-from .data_types import coerce_value
+from .data_types import (coerce_value, get_primitive_data_type)
+from ..presentation.types import get_type_by_name
#
@@ -149,16 +150,22 @@ def validate_required_values(context, presentation, values, definitions):
def merge_raw_parameter_definition(context, presentation, raw_property_definition,
our_property_definition, field_name, property_name):
- # Check if we changed the type
- # TODO: allow a sub-type?
- type1 = raw_property_definition.get('type')
- type2 = our_property_definition.type
+ # Check if we changed the parameter type
+ type1_name = raw_property_definition.get('type')
+ type1 = get_type_by_name(context, type1_name, 'data_types')
+ if type1 is None:
+ type1 = get_primitive_data_type(type1_name)
+ our_property_definition._reset_method_cache()
+ type2 = our_property_definition._get_type(context)
+
if type1 != type2:
- context.validation.report(
- 'override changes type from "%s" to "%s" for property "%s" in "%s"'
- % (type1, type2, property_name, presentation._fullname),
- locator=presentation._get_child_locator(field_name, property_name),
- level=Issue.BETWEEN_TYPES)
+ if not hasattr(type1, '_is_descendant') or not type1._is_descendant(context, type2):
+ context.validation.report(
+ 'property definition type "{0}" is not a descendant of overridden '
+ 'property definition type "{1}"' \
+ .format(type1_name, type2._name),
+ locator=presentation._get_child_locator(field_name, property_name),
+ level=Issue.BETWEEN_TYPES)
merge(raw_property_definition, our_property_definition._raw)
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
index 920ebed..5f9750e 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -18,7 +18,8 @@ def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable
"""
Converts a type name to its full type name, or else returns it unchanged.
- Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
+ Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+ ``_extensions`` field. See also
:class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
Can be used as the conversion function argument in ``type_validator`` and
@@ -36,9 +37,10 @@ def convert_name_to_full_type_name(context, name, types_dict): # pylint: disable
def get_type_by_name(context, name, *types_dict_names):
"""
- Gets a type either by its full name or its shorthand name or typequalified name.
+ Gets a type either by its full name or its shorthand name or type-qualified name.
- Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
+ Works by checking for ``shorthand_name`` and ``type_qualified_name`` in the types'
+ ``_extensions`` field. See also
:class:`~aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
The arguments from the third onwards are used to locate a nested field under
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index 787aac2..b662a20 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -193,6 +193,17 @@ class DataType(ExtensiblePresentation):
return get_data_type(context, self, 'derived_from', allow_none=True)
@cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ if not hasattr(the_type, '_name'):
+ # Must be a primitive type
+ return self._get_primitive_ancestor(context) == the_type
+ if the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
def _get_primitive_ancestor(self, context):
parent = self._get_parent(context)
if parent is not None:
@@ -387,6 +398,14 @@ class InterfaceType(ExtensiblePresentation):
'interface_types')
@cachedmethod
+ def _is_descendant(self, context, the_type):
+ if the_type is None:
+ return False
+ elif the_type._name == self._name:
+ return True
+ return self._is_descendant(context, the_type._get_parent(context))
+
+ @cachedmethod
def _get_inputs(self, context):
return FrozenDict(get_inherited_parameter_definitions(context, self, 'inputs'))
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a9fb6fad/tests/end2end/test_hello_world.py
----------------------------------------------------------------------
diff --git a/tests/end2end/test_hello_world.py b/tests/end2end/test_hello_world.py
index 5e4d7fd..094ffc3 100644
--- a/tests/end2end/test_hello_world.py
+++ b/tests/end2end/test_hello_world.py
@@ -20,7 +20,7 @@ from .. import helpers
def test_hello_world(testenv):
- hello_world_template_uri = helpers.get_example_uri('hello-world', 'helloworld.yaml')
+ hello_world_template_uri = helpers.get_example_uri('hello-world', 'hello-world.yaml')
service_name = testenv.install_service(hello_world_template_uri)
try: