1 # -*- coding: utf-8 -*-
3 #######################################################################################
4 # This file is part of OSM RO module
6 # Copyright ETSI Contributors and Others.
8 # Licensed under the Apache License, Version 2.0 (the "License"); you may
9 # not use this file except in compliance with the License. You may obtain
10 # a copy of the License at
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 # License for the specific language governing permissions and limitations
19 #######################################################################################
20 # This work has been performed in the context of the TeraFlow Project -
21 # funded by the European Commission under Grant number 101015857 through the
22 # Horizon 2020 program.
24 # - Lluis Gifre <lluis.gifre@cttc.es>
25 # - Ricard Vilalta <ricard.vilalta@cttc.es>
26 #######################################################################################
28 """This file contains the TransportApiClient class used by the Transport API
29 (TAPI) WIM connector to interact with the underlying WIM."""
33 from .exceptions
import (
34 WimTapiConnectivityServiceCreateFailed
,
35 WimTapiConnectivityServiceDeleteFailed
,
36 WimTapiConnectivityServiceGetStatusFailed
,
37 WimTapiServerNotAvailable
,
38 WimTapiServerRequestFailed
,
40 from .log_messages
import (
42 LOG_MSG_CREATE_REQUEST
,
44 LOG_MSG_DELETE_REQUEST
,
45 LOG_MSG_GET_STATUS_REPLY
,
46 LOG_MSG_GET_STATUS_REQUEST
,
48 from .message_composers
import (
49 compose_create_request
,
50 compose_delete_request
,
55 SUCCESS_HTTP_CODES
= {
56 requests
.codes
.ok
, # pylint: disable=no-member
57 requests
.codes
.created
, # pylint: disable=no-member
58 requests
.codes
.accepted
, # pylint: disable=no-member
59 requests
.codes
.no_content
, # pylint: disable=no-member
62 RESTCONF_DATA_URL
= "{:s}/restconf/data"
63 RESTCONF_OPER_URL
= "{:s}/restconf/operations"
65 CONTEXT_URL
= RESTCONF_DATA_URL
+ "/tapi-common:context"
66 CTX_SIPS_URL
= CONTEXT_URL
+ "/service-interface-point"
67 CONN_CTX_URL
= CONTEXT_URL
+ "/tapi-connectivity:connectivity-context"
68 CONN_SVC_URL
= CONN_CTX_URL
+ "/connectivity-service"
69 DELETE_URL
= RESTCONF_OPER_URL
+ "/tapi-connectivity:delete-connectivity-service"
72 class TransportApiClient
:
73 def __init__(self
, logger
, wim
, wim_account
, config
) -> None:
75 self
.wim_url
= wim
["wim_url"]
77 user
= wim_account
.get("user")
78 password
= wim_account
.get("password")
81 if user
is None or user
== "" or password
is None or password
== ""
85 self
.headers
= {"Content-Type": "application/json"}
86 self
.timeout
= int(config
.get("timeout", DEFAULT_TIMEOUT
))
88 def get_root_context(self
):
89 context_url
= CONTEXT_URL
.format(self
.wim_url
)
92 response
= requests
.get(
93 context_url
, auth
=self
.auth
, headers
=self
.headers
, timeout
=self
.timeout
95 http_code
= response
.status_code
96 except requests
.exceptions
.RequestException
as e
:
97 raise WimTapiServerNotAvailable(str(e
))
100 raise WimTapiServerRequestFailed(
101 "Unexpected status code", http_code
=http_code
104 return response
.json()
106 def get_service_interface_points(self
):
107 get_sips_url
= CTX_SIPS_URL
.format(self
.wim_url
)
110 response
= requests
.get(
111 get_sips_url
, auth
=self
.auth
, headers
=self
.headers
, timeout
=self
.timeout
113 http_code
= response
.status_code
114 except requests
.exceptions
.RequestException
as e
:
115 raise WimTapiServerNotAvailable(str(e
))
118 raise WimTapiServerRequestFailed(
119 "Unexpected status code", http_code
=http_code
122 response
= response
.json()
123 response
= response
.get("tapi-common:service-interface-point", [])
124 return {sip
["uuid"]: sip
for sip
in response
}
126 def get_service_status(self
, name
, service_uuid
):
127 self
.logger
.debug(LOG_MSG_GET_STATUS_REQUEST
.format(name
, service_uuid
))
130 services_url
= CONN_SVC_URL
.format(self
.wim_url
)
131 response
= requests
.get(
132 services_url
, auth
=self
.auth
, headers
=self
.headers
, timeout
=self
.timeout
135 LOG_MSG_GET_STATUS_REPLY
.format(
136 name
, service_uuid
, response
.status_code
, response
.text
139 except requests
.exceptions
.ConnectionError
as e
:
140 status_code
= e
.response
.status_code
if e
.response
is not None else 500
141 content
= e
.response
.text
if e
.response
is not None else ""
142 raise WimTapiConnectivityServiceGetStatusFailed(
143 name
, service_uuid
, status_code
, content
146 if response
.status_code
not in SUCCESS_HTTP_CODES
:
147 raise WimTapiConnectivityServiceGetStatusFailed(
148 name
, service_uuid
, response
.status_code
, response
.text
151 json_response
= response
.json()
152 connectivity_services
= json_response
.get(
153 "tapi-connectivity:connectivity-service", []
155 connectivity_service
= next(
159 for connectivity_service
in connectivity_services
160 if connectivity_service
.get("uuid") == service_uuid
166 if connectivity_service
is None:
167 service_status
= {"sdn_status": "ERROR"}
169 service_status
= {"sdn_status": "ACTIVE"}
170 return service_status
178 requested_capacity
=None,
179 vlan_constraint
=None,
181 request_create
= compose_create_request(
184 bidirectional
=bidirectional
,
185 requested_capacity
=requested_capacity
,
186 vlan_constraint
=vlan_constraint
,
189 LOG_MSG_CREATE_REQUEST
.format(name
, service_uuid
, str(request_create
))
193 create_url
= CONN_CTX_URL
.format(self
.wim_url
)
194 response
= requests
.post(
195 create_url
, headers
=self
.headers
, json
=request_create
, auth
=self
.auth
198 LOG_MSG_CREATE_REPLY
.format(
199 name
, service_uuid
, response
.status_code
, response
.text
202 except requests
.exceptions
.ConnectionError
as e
:
203 status_code
= e
.response
.status_code
if e
.response
is not None else 500
204 content
= e
.response
.text
if e
.response
is not None else ""
205 raise WimTapiConnectivityServiceCreateFailed(
206 name
, service_uuid
, status_code
, content
209 if response
.status_code
not in SUCCESS_HTTP_CODES
:
210 raise WimTapiConnectivityServiceCreateFailed(
211 name
, service_uuid
, response
.status_code
, response
.text
214 def delete_service(self
, name
, service_uuid
):
215 request_delete
= compose_delete_request(service_uuid
)
217 LOG_MSG_DELETE_REQUEST
.format(name
, service_uuid
, str(request_delete
))
221 delete_url
= DELETE_URL
.format(self
.wim_url
)
222 response
= requests
.post(
223 delete_url
, headers
=self
.headers
, json
=request_delete
, auth
=self
.auth
226 LOG_MSG_DELETE_REPLY
.format(
227 name
, service_uuid
, response
.status_code
, response
.text
230 except requests
.exceptions
.ConnectionError
as e
:
231 status_code
= e
.response
.status_code
if e
.response
is not None else 500
232 content
= e
.response
.text
if e
.response
is not None else ""
233 raise WimTapiConnectivityServiceDeleteFailed(
234 name
, service_uuid
, status_code
, content
237 if response
.status_code
not in SUCCESS_HTTP_CODES
:
238 raise WimTapiConnectivityServiceDeleteFailed(
239 name
, service_uuid
, response
.status_code
, response
.text