Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions platform/src/main/python/dlpx/virtualization/platform/_linked.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
"""LinkedOperations for the Virtualization Platform

"""
import inspect
import json

from dlpx.virtualization.api import common_pb2, platform_pb2
from dlpx.virtualization.common import RemoteConnection, RemoteEnvironment
from dlpx.virtualization.common.exceptions import PluginRuntimeError
from dlpx.virtualization.platform import (DirectSource, Mount,
MountSpecification, StagedSource,
Status, PhysicalSource)
Status, PhysicalSource, PitParameters)
from dlpx.virtualization.platform import validation_util as v
from dlpx.virtualization.platform.exceptions import (
IncorrectReturnTypeError, OperationAlreadyDefinedError,
Expand Down Expand Up @@ -265,12 +266,17 @@ def to_protobuf(snapshot):
None if snap_params is None else
SnapshotParametersDefinition.from_dict(snap_params))

snapshot = self.post_snapshot_impl(
result = self.post_snapshot_impl(
direct_source=direct_source,
repository=repository,
source_config=source_config,
optional_snapshot_parameters=snapshot_parameters)

if isinstance(result, tuple):
snapshot, pit_parameters = result
else:
snapshot, pit_parameters = result, None

# Validate that this is a SnapshotDefinition object
if not isinstance(snapshot, SnapshotDefinition):
raise IncorrectReturnTypeError(Op.LINKED_POST_SNAPSHOT,
Expand All @@ -280,6 +286,9 @@ def to_protobuf(snapshot):
platform_pb2.DirectPostSnapshotResponse())
direct_post_snapshot_response.return_value.snapshot.CopyFrom(
to_protobuf(snapshot))
if pit_parameters is not None:
direct_post_snapshot_response.return_value.pit_parameters.CopyFrom(
pit_parameters.to_proto())

return direct_post_snapshot_response

Expand Down Expand Up @@ -529,19 +538,27 @@ def to_protobuf(snapshot):
None if snap_params is None else
SnapshotParametersDefinition.from_dict(snap_params))

snapshot = self.post_snapshot_impl(
result = self.post_snapshot_impl(
staged_source=staged_source,
repository=repository,
source_config=source_config,
optional_snapshot_parameters=snapshot_parameters)

if isinstance(result, tuple):
snapshot, pit_parameters = result
else:
snapshot, pit_parameters = result, None

# Validate that this is a SnapshotDefinition object
if not isinstance(snapshot, SnapshotDefinition):
raise IncorrectReturnTypeError(Op.LINKED_POST_SNAPSHOT,
type(snapshot), SnapshotDefinition)

response = platform_pb2.StagedPostSnapshotResponse()
response.return_value.snapshot.CopyFrom(to_protobuf(snapshot))
if pit_parameters is not None:
response.return_value.pit_parameters.CopyFrom(
pit_parameters.to_proto())

return response

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
__all__ = [
"VirtualSource", "StagedSource", "DirectSource", "PhysicalSource",
"Status", "MigrationType", "Mount", "OwnershipSpecification",
"MountSpecification"
"MountSpecification", "LogFile", "PitParameters"
]


Expand Down Expand Up @@ -287,6 +287,76 @@ def gid(self):
return self._gid


class LogFile(object):
def __init__(self, filename, location, timestamp, parameters=None):
self._filename = filename
self._location = location
self._timestamp = timestamp
self._parameters = parameters or {}

@property
def filename(self):
return self._filename

@property
def location(self):
return self._location

@property
def timestamp(self):
return self._timestamp

@property
def parameters(self):
return self._parameters

def to_proto(self):
from dlpx.virtualization.api import common_pb2
proto = common_pb2.LogFile()
proto.filename = self._filename
proto.location = self._location
proto.timestamp.FromDatetime(self._timestamp)
proto.parameters.update(self._parameters)
return proto

@classmethod
def from_proto(cls, proto):
return cls(
filename=proto.filename,
location=proto.location,
timestamp=proto.timestamp.ToDatetime(),
parameters=dict(proto.parameters),
)


class PitParameters(object):
def __init__(self, pit_timestamp, log_files=None):
self._pit_timestamp = pit_timestamp
self._log_files = log_files or []

@property
def pit_timestamp(self):
return self._pit_timestamp

@property
def log_files(self):
return self._log_files

def to_proto(self):
from dlpx.virtualization.api import common_pb2
proto = common_pb2.PitParameters()
proto.pit_timestamp.FromDatetime(self._pit_timestamp)
proto.log_files.extend([lf.to_proto() for lf in self._log_files])
return proto

@classmethod
def from_proto(cls, proto):
return cls(
pit_timestamp=proto.pit_timestamp.ToDatetime(),
log_files=[LogFile.from_proto(lf) for lf in proto.log_files],
)


class MountSpecification(object):
def __init__(self, mounts, ownership_specification=None):
if not isinstance(mounts, list):
Expand Down
32 changes: 24 additions & 8 deletions platform/src/main/python/dlpx/virtualization/platform/_virtual.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
"""VirtualOperations for the Virtualization Platform

"""
import inspect
import json

from dlpx.virtualization.api import common_pb2, platform_pb2
from dlpx.virtualization.common import RemoteConnection, RemoteEnvironment
from dlpx.virtualization.platform import (Mount, MountSpecification, Status,
VirtualSource, PhysicalSource)
VirtualSource, PhysicalSource,
PitParameters)
from dlpx.virtualization.platform import validation_util as v
from dlpx.virtualization.platform.exceptions import (
IncorrectReturnTypeError, OperationAlreadyDefinedError,
Expand Down Expand Up @@ -221,9 +223,16 @@ def _internal_configure(self, request):
snapshot = SnapshotDefinition.from_dict(
json.loads(request.snapshot.parameters.json))

config = self.configure_impl(virtual_source=virtual_source,
repository=repository,
snapshot=snapshot)
pit_parameters = (
PitParameters.from_proto(request.pit_parameters)
if request.HasField('pit_parameters') else None)

kwargs = dict(virtual_source=virtual_source,
repository=repository,
snapshot=snapshot)
if 'pit_parameters' in inspect.signature(self.configure_impl).parameters:
kwargs['pit_parameters'] = pit_parameters
config = self.configure_impl(**kwargs)

# Validate that this is a SourceConfigDefinition object.
if not isinstance(config, SourceConfigDefinition):
Expand Down Expand Up @@ -382,10 +391,17 @@ def _internal_reconfigure(self, request):
repository = RepositoryDefinition.from_dict(
json.loads(request.repository.parameters.json))

config = self.reconfigure_impl(snapshot=snapshot,
repository=repository,
source_config=source_config,
virtual_source=virtual_source)
pit_parameters = (
PitParameters.from_proto(request.pit_parameters)
if request.HasField('pit_parameters') else None)

kwargs = dict(snapshot=snapshot,
repository=repository,
source_config=source_config,
virtual_source=virtual_source)
if 'pit_parameters' in inspect.signature(self.reconfigure_impl).parameters:
kwargs['pit_parameters'] = pit_parameters
config = self.reconfigure_impl(**kwargs)

# Validate that this is a SourceConfigDefinition object.
if not isinstance(config, SourceConfigDefinition):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,23 @@ def _check_upgrade_args(upgrade_operations, expected_upgrade_args):
return warnings


# Args that plugins may optionally declare to opt into SDK-provided features.
# The SDK passes these only when the plugin's function signature includes them.
_OPTIONAL_ARGS = frozenset({'pit_parameters'})


def _check_args(method_name, expected_args, actual_args):
warnings = []

if len(expected_args) != len(actual_args):
required_actual = [a for a in actual_args if a not in _OPTIONAL_ARGS]

if len(expected_args) != len(required_actual):
warnings.append('Number of arguments do not match in method {}.'
' Expected: {}, Found: {}.'.format(
method_name, list(expected_args), actual_args))

if not all(arg in expected_args for arg in actual_args):
if not all(arg in expected_args or arg in _OPTIONAL_ARGS
for arg in actual_args):
warnings.append('Named argument mismatch in method {}.'
' Expected: {}, Found: {}.'.format(
method_name, list(expected_args), actual_args))
Expand Down