Commit 5f2d8efd authored by Pavel Spirek's avatar Pavel Spirek

Transactions are started implicitly

parent 712f331a
......@@ -20,7 +20,7 @@ CONFIG_HTTP = {
"DOC_ROOT": "doc-root",
"DOC_DEFAULT_NAME": "index.html",
"API_ROOT": "/restconf",
"API_ROOT_STAGING": "/restconf_staging",
"API_ROOT_RUNNING": "/restconf_running",
"SERVER_NAME": "jetconf-h2",
"UPLOAD_SIZE_LIMIT": 1,
"LISTEN_LOCALHOST_ONLY": False,
......@@ -49,14 +49,14 @@ CONFIG = {
}
API_ROOT_data = os.path.join(CONFIG_HTTP["API_ROOT"], "data")
API_ROOT_STAGING_data = os.path.join(CONFIG_HTTP["API_ROOT_STAGING"], "data")
API_ROOT_RUNNING_data = os.path.join(CONFIG_HTTP["API_ROOT_RUNNING"], "data")
API_ROOT_ops = os.path.join(CONFIG_HTTP["API_ROOT"], "operations")
API_ROOT_ylv = os.path.join(CONFIG_HTTP["API_ROOT"], "yang-library-version")
def load_config(filename: str) -> bool:
global API_ROOT_data
global API_ROOT_STAGING_data
global API_ROOT_RUNNING_data
global API_ROOT_ops
global API_ROOT_ylv
......@@ -70,7 +70,7 @@ def load_config(filename: str) -> bool:
# Shortcuts
API_ROOT_data = os.path.join(CONFIG_HTTP["API_ROOT"], "data")
API_ROOT_STAGING_data = os.path.join(CONFIG_HTTP["API_ROOT_STAGING"], "data")
API_ROOT_RUNNING_data = os.path.join(CONFIG_HTTP["API_ROOT_RUNNING"], "data")
API_ROOT_ops = os.path.join(CONFIG_HTTP["API_ROOT"], "operations")
API_ROOT_ylv = os.path.join(CONFIG_HTTP["API_ROOT"], "yang-library-version")
......
......@@ -146,7 +146,7 @@ class UsrChangeJournal:
if len(self._journal) == 0:
return False
if hash(ds.get_data_root()) == hash(self.get_root_head()):
if hash(ds.get_data_root()) == hash(self._root_origin):
info("Commiting new configuration (swapping roots)")
# Set new root
nr = self.get_root_head()
......@@ -380,7 +380,10 @@ class BaseDatastore:
try:
root = self.get_data_root_staging(rpc.username)
except StagingDataException:
root = self._data
# root = self._data
info("Starting transaction for user \"{}\"".format(rpc.username))
self.make_user_journal(rpc.username, None)
root = self.get_data_root_staging(rpc.username)
else:
root = self._data
......
......@@ -13,7 +13,7 @@ from yangson.exceptions import YangsonException, NonexistentSchemaNode, SchemaEr
from yangson.schemanode import ContainerNode, ListNode, GroupNode, LeafListNode, LeafNode
from yangson.instance import NonexistentInstance, InstanceValueError, RootNode
from .config import CONFIG_GLOBAL, CONFIG_HTTP, CONFIG_NACM, API_ROOT_data, API_ROOT_STAGING_data, API_ROOT_ops
from .config import CONFIG_GLOBAL, CONFIG_HTTP, CONFIG_NACM, API_ROOT_data, API_ROOT_RUNNING_data, API_ROOT_ops
from .helpers import CertHelpers, DateTimeHelpers, ErrorHelpers, LogHelpers, SSLCertT
from .errors import BackendError
from .nacm import NacmForbiddenError
......@@ -312,19 +312,19 @@ def create_get_api(ds: BaseDatastore):
info("[{}] api_get: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(API_ROOT_data):]
http_resp = _get(ds, headers, api_pth, username)
http_resp = _get(ds, headers, api_pth, username, staging=True)
return http_resp
return get_api_closure
def create_get_staging_api(ds: BaseDatastore):
def create_get_running_api(ds: BaseDatastore):
def get_staging_api_closure(headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
info("[{}] api_get_staging: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(API_ROOT_STAGING_data):]
http_resp = _get(ds, headers, api_pth, username, staging=True)
api_pth = headers[":path"][len(API_ROOT_RUNNING_data):]
http_resp = _get(ds, headers, api_pth, username, staging=False)
return http_resp
return get_staging_api_closure
......@@ -390,7 +390,13 @@ def _post(ds: BaseDatastore, pth: str, username: str, data: str) -> HttpResponse
ds.lock_data(username)
try:
new_root = ds.create_node_rpc(ds.get_data_root_staging(rpc1.username), rpc1, json_data)
try:
staging_root = ds.get_data_root_staging(rpc1.username)
except StagingDataException:
info("Starting transaction for user \"{}\"".format(rpc1.username))
ds.make_user_journal(rpc1.username, None)
staging_root = ds.get_data_root_staging(rpc1.username)
new_root = ds.create_node_rpc(staging_root, rpc1, json_data)
ds.add_to_journal_rpc(ChangeType.CREATE, rpc1, json_data, *new_root)
http_resp = HttpResponse.empty(HttpStatus.Created)
except NacmForbiddenError as e:
......@@ -414,7 +420,7 @@ def _post(ds: BaseDatastore, pth: str, username: str, data: str) -> HttpResponse
ERRTAG_OPNOTSUPPORTED,
exception=e
)
except (InstanceValueError, StagingDataException, YangsonException, ValueError) as e:
except (InstanceValueError, YangsonException, ValueError) as e:
http_resp = HttpResponse.error(
HttpStatus.BadRequest,
RestconfErrType.Protocol,
......@@ -482,7 +488,13 @@ def _put(ds: BaseDatastore, pth: str, username: str, data: str) -> HttpResponse:
ds.lock_data(username)
try:
new_root = ds.update_node_rpc(ds.get_data_root_staging(rpc1.username), rpc1, json_data)
try:
staging_root = ds.get_data_root_staging(rpc1.username)
except StagingDataException:
info("Starting transaction for user \"{}\"".format(rpc1.username))
ds.make_user_journal(rpc1.username, None)
staging_root = ds.get_data_root_staging(rpc1.username)
new_root = ds.update_node_rpc(staging_root, rpc1, json_data)
ds.add_to_journal_rpc(ChangeType.REPLACE, rpc1, json_data, *new_root)
http_resp = HttpResponse.empty(HttpStatus.NoContent, status_in_body=False)
except NacmForbiddenError as e:
......@@ -554,7 +566,13 @@ def _delete(ds: BaseDatastore, pth: str, username: str) -> HttpResponse:
ds.lock_data(username)
try:
new_root = ds.delete_node_rpc(ds.get_data_root_staging(rpc1.username), rpc1)
try:
staging_root = ds.get_data_root_staging(rpc1.username)
except StagingDataException:
info("Starting transaction for user \"{}\"".format(rpc1.username))
ds.make_user_journal(rpc1.username, None)
staging_root = ds.get_data_root_staging(rpc1.username)
new_root = ds.delete_node_rpc(staging_root, rpc1)
ds.add_to_journal_rpc(ChangeType.DELETE, rpc1, None, *new_root)
http_resp = HttpResponse.empty(HttpStatus.NoContent, status_in_body=False)
except NacmForbiddenError as e:
......
......@@ -9,11 +9,12 @@ class OpHandlersContainer:
self.ds = ds
def jetconf_conf_start(self, rpc: RpcInfo) -> JsonNodeT:
try:
transaction_opts = rpc.op_input_args["options"]
except (TypeError, KeyError):
transaction_opts = None
self.ds.make_user_journal(rpc.username, transaction_opts)
# try:
# transaction_opts = rpc.op_input_args["options"]
# except (TypeError, KeyError):
# transaction_opts = None
# self.ds.make_user_journal(rpc.username, transaction_opts)
self.ds.make_user_journal(rpc.username, None)
ret_data = {"status": "OK"}
return ret_data
......@@ -32,7 +33,7 @@ class OpHandlersContainer:
return ret_data
def jetconf_conf_drop(self, rpc: RpcInfo) -> JsonNodeT:
def jetconf_conf_reset(self, rpc: RpcInfo) -> JsonNodeT:
self.ds.drop_user_journal(rpc.username)
ret_data = {"status": "OK"}
return ret_data
......@@ -91,7 +92,7 @@ def register_op_handlers(ds: BaseDatastore):
op_handlers_obj = OpHandlersContainer(ds)
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_start, "jetconf:conf-start")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_status, "jetconf:conf-status")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_drop, "jetconf:conf-drop")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_reset, "jetconf:conf-reset")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_commit, "jetconf:conf-commit")
OP_HANDLERS.register(op_handlers_obj.jetconf_get_schema_digest, "jetconf:get-schema-digest")
OP_HANDLERS.register(op_handlers_obj.jetconf_get_list_length, "jetconf:get-list-length")
......@@ -13,7 +13,7 @@ from h2.events import DataReceived, RequestReceived, RemoteSettingsChanged, Stre
from . import http_handlers as handlers
from .http_handlers import HttpResponse, HttpStatus, RestconfErrType, ERRTAG_MALFORMED, ERRTAG_OPNOTSUPPORTED, ERRTAG_REQLARGE
from .config import CONFIG_HTTP, API_ROOT_data, API_ROOT_STAGING_data, API_ROOT_ops, API_ROOT_ylv
from .config import CONFIG_HTTP, API_ROOT_data, API_ROOT_RUNNING_data, API_ROOT_ops, API_ROOT_ylv
from .data import BaseDatastore
from .helpers import SSLCertT, LogHelpers
......@@ -260,14 +260,14 @@ class RestServer:
api_get_root = handlers.api_root_handler
api_get_ylv = handlers.api_ylv_handler
api_get = handlers.create_get_api(datastore)
api_get_st = handlers.create_get_staging_api(datastore)
api_get_run = handlers.create_get_running_api(datastore)
api_post = handlers.create_post_api(datastore)
api_put = handlers.create_put_api(datastore)
api_delete = handlers.create_api_delete(datastore)
api_op = handlers.create_api_op(datastore)
self.http_handlers.register(lambda m, p: (m == "GET") and (p.startswith(API_ROOT_data)), api_get)
self.http_handlers.register(lambda m, p: (m == "GET") and (p.startswith(API_ROOT_STAGING_data)), api_get_st)
self.http_handlers.register(lambda m, p: (m == "GET") and (p.startswith(API_ROOT_RUNNING_data)), api_get_run)
self.http_handlers.register(lambda m, p: (m == "GET") and (p == API_ROOT_ylv), api_get_ylv)
self.http_handlers.register(lambda m, p: (m == "GET") and (p == CONFIG_HTTP["API_ROOT"]), api_get_root)
self.http_handlers.register(lambda m, p: (m == "POST") and (p.startswith(API_ROOT_data)), api_post)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment