|
17 | 17 |
|
18 | 18 | import re |
19 | 19 |
|
20 | | -from google.longrunning import operations_pb2 |
21 | | - |
22 | | -from gcloud._helpers import _pb_timestamp_to_datetime |
23 | 20 | from gcloud.bigtable._generated import ( |
24 | 21 | instance_pb2 as data_v2_pb2) |
25 | 22 | from gcloud.bigtable._generated import ( |
|
29 | 26 | from gcloud.bigtable.cluster import Cluster |
30 | 27 | from gcloud.bigtable.cluster import DEFAULT_SERVE_NODES |
31 | 28 | from gcloud.bigtable.table import Table |
| 29 | +from gcloud.operation import Operation |
| 30 | +from gcloud.operation import _compute_type_url |
| 31 | +from gcloud.operation import _register_type_url |
32 | 32 |
|
33 | 33 |
|
34 | 34 | _EXISTING_INSTANCE_LOCATION_ID = 'see-existing-cluster' |
35 | 35 | _INSTANCE_NAME_RE = re.compile(r'^projects/(?P<project>[^/]+)/' |
36 | 36 | r'instances/(?P<instance_id>[a-z][-a-z0-9]*)$') |
37 | | -_OPERATION_NAME_RE = re.compile(r'^operations/projects/([^/]+)/' |
38 | | - r'instances/([a-z][-a-z0-9]*)/' |
39 | | - r'locations/(?P<location_id>[a-z][-a-z0-9]*)/' |
40 | | - r'operations/(?P<operation_id>\d+)$') |
41 | | -_TYPE_URL_BASE = 'type.googleapis.com/google.bigtable.' |
42 | | -_ADMIN_TYPE_URL_BASE = _TYPE_URL_BASE + 'admin.v2.' |
43 | | -_INSTANCE_CREATE_METADATA = _ADMIN_TYPE_URL_BASE + 'CreateInstanceMetadata' |
44 | | -_TYPE_URL_MAP = { |
45 | | - _INSTANCE_CREATE_METADATA: messages_v2_pb2.CreateInstanceMetadata, |
46 | | -} |
| 37 | + |
| 38 | + |
| 39 | +_CREATE_INSTANCE_METADATA_URL = _compute_type_url( |
| 40 | + messages_v2_pb2.CreateInstanceMetadata) |
| 41 | +_register_type_url( |
| 42 | + _CREATE_INSTANCE_METADATA_URL, messages_v2_pb2.CreateInstanceMetadata) |
47 | 43 |
|
48 | 44 |
|
49 | 45 | def _prepare_create_request(instance): |
@@ -71,125 +67,6 @@ def _prepare_create_request(instance): |
71 | 67 | return message |
72 | 68 |
|
73 | 69 |
|
74 | | -def _parse_pb_any_to_native(any_val, expected_type=None): |
75 | | - """Convert a serialized "google.protobuf.Any" value to actual type. |
76 | | -
|
77 | | - :type any_val: :class:`google.protobuf.any_pb2.Any` |
78 | | - :param any_val: A serialized protobuf value container. |
79 | | -
|
80 | | - :type expected_type: str |
81 | | - :param expected_type: (Optional) The type URL we expect ``any_val`` |
82 | | - to have. |
83 | | -
|
84 | | - :rtype: object |
85 | | - :returns: The de-serialized object. |
86 | | - :raises: :class:`ValueError <exceptions.ValueError>` if the |
87 | | - ``expected_type`` does not match the ``type_url`` on the input. |
88 | | - """ |
89 | | - if expected_type is not None and expected_type != any_val.type_url: |
90 | | - raise ValueError('Expected type: %s, Received: %s' % ( |
91 | | - expected_type, any_val.type_url)) |
92 | | - container_class = _TYPE_URL_MAP[any_val.type_url] |
93 | | - return container_class.FromString(any_val.value) |
94 | | - |
95 | | - |
96 | | -def _process_operation(operation_pb): |
97 | | - """Processes a create protobuf response. |
98 | | -
|
99 | | - :type operation_pb: :class:`google.longrunning.operations_pb2.Operation` |
100 | | - :param operation_pb: The long-running operation response from a |
101 | | - Create/Update/Undelete instance request. |
102 | | -
|
103 | | - :rtype: (int, str, datetime) |
104 | | - :returns: (operation_id, location_id, operation_begin). |
105 | | - :raises: :class:`ValueError <exceptions.ValueError>` if the operation name |
106 | | - doesn't match the :data:`_OPERATION_NAME_RE` regex. |
107 | | - """ |
108 | | - match = _OPERATION_NAME_RE.match(operation_pb.name) |
109 | | - if match is None: |
110 | | - raise ValueError('Operation name was not in the expected ' |
111 | | - 'format after instance creation.', |
112 | | - operation_pb.name) |
113 | | - location_id = match.group('location_id') |
114 | | - operation_id = int(match.group('operation_id')) |
115 | | - |
116 | | - request_metadata = _parse_pb_any_to_native(operation_pb.metadata) |
117 | | - operation_begin = _pb_timestamp_to_datetime( |
118 | | - request_metadata.request_time) |
119 | | - |
120 | | - return operation_id, location_id, operation_begin |
121 | | - |
122 | | - |
123 | | -class Operation(object): |
124 | | - """Representation of a Google API Long-Running Operation. |
125 | | -
|
126 | | - In particular, these will be the result of operations on |
127 | | - instances using the Cloud Bigtable API. |
128 | | -
|
129 | | - :type op_type: str |
130 | | - :param op_type: The type of operation being performed. Expect |
131 | | - ``create``, ``update`` or ``undelete``. |
132 | | -
|
133 | | - :type op_id: int |
134 | | - :param op_id: The ID of the operation. |
135 | | -
|
136 | | - :type begin: :class:`datetime.datetime` |
137 | | - :param begin: The time when the operation was started. |
138 | | -
|
139 | | - :type location_id: str |
140 | | - :param location_id: ID of the location in which the operation is running |
141 | | -
|
142 | | - :type instance: :class:`Instance` |
143 | | - :param instance: The instance that created the operation. |
144 | | - """ |
145 | | - |
146 | | - def __init__(self, op_type, op_id, begin, location_id, instance=None): |
147 | | - self.op_type = op_type |
148 | | - self.op_id = op_id |
149 | | - self.begin = begin |
150 | | - self.location_id = location_id |
151 | | - self._instance = instance |
152 | | - self._complete = False |
153 | | - |
154 | | - def __eq__(self, other): |
155 | | - if not isinstance(other, self.__class__): |
156 | | - return False |
157 | | - return (other.op_type == self.op_type and |
158 | | - other.op_id == self.op_id and |
159 | | - other.begin == self.begin and |
160 | | - other.location_id == self.location_id and |
161 | | - other._instance == self._instance and |
162 | | - other._complete == self._complete) |
163 | | - |
164 | | - def __ne__(self, other): |
165 | | - return not self.__eq__(other) |
166 | | - |
167 | | - def finished(self): |
168 | | - """Check if the operation has finished. |
169 | | -
|
170 | | - :rtype: bool |
171 | | - :returns: A boolean indicating if the current operation has completed. |
172 | | - :raises: :class:`ValueError <exceptions.ValueError>` if the operation |
173 | | - has already completed. |
174 | | - """ |
175 | | - if self._complete: |
176 | | - raise ValueError('The operation has completed.') |
177 | | - |
178 | | - operation_name = ( |
179 | | - 'operations/%s/locations/%s/operations/%d' % |
180 | | - (self._instance.name, self.location_id, self.op_id)) |
181 | | - request_pb = operations_pb2.GetOperationRequest(name=operation_name) |
182 | | - # We expect a `google.longrunning.operations_pb2.Operation`. |
183 | | - operation_pb = self._instance._client._operations_stub.GetOperation( |
184 | | - request_pb) |
185 | | - |
186 | | - if operation_pb.done: |
187 | | - self._complete = True |
188 | | - return True |
189 | | - else: |
190 | | - return False |
191 | | - |
192 | | - |
193 | 70 | class Instance(object): |
194 | 71 | """Representation of a Google Cloud Bigtable Instance. |
195 | 72 |
|
@@ -359,8 +236,10 @@ def create(self): |
359 | 236 | # We expect a `google.longrunning.operations_pb2.Operation`. |
360 | 237 | operation_pb = self._client._instance_stub.CreateInstance(request_pb) |
361 | 238 |
|
362 | | - op_id, loc_id, op_begin = _process_operation(operation_pb) |
363 | | - return Operation('create', op_id, op_begin, loc_id, instance=self) |
| 239 | + operation = Operation.from_pb(operation_pb, self._client) |
| 240 | + operation.target = self |
| 241 | + operation.metadata['request_type'] = 'CreateInstance' |
| 242 | + return operation |
364 | 243 |
|
365 | 244 | def update(self): |
366 | 245 | """Update this instance. |
|
0 commit comments