| # Copyright 2017 Google Inc. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Host Info APIs implemented using Google Cloud Endpoints.""" |
| |
| import datetime |
| import endpoints |
| import logging |
| |
| from google.appengine.api import users |
| from google.appengine.ext import ndb |
| |
| from webapp.src import vtslab_status as Status |
| from webapp.src.endpoint import endpoint_base |
| from webapp.src.proto import model |
| |
| HOST_INFO_RESOURCE = endpoints.ResourceContainer(model.HostInfoMessage) |
| |
| # Product type name for null device. |
| _NULL_DEVICE_PRODUCT_TYPE = "null" |
| |
| |
| def AddNullDevices(hostname, null_device_count): |
| """Adds null devices to DeviceModel data store. |
| |
| Args: |
| hostname: string, the host name. |
| null_device_count: integer, the number of null devices. |
| """ |
| device_query = model.DeviceModel.query( |
| model.DeviceModel.hostname == hostname, |
| model.DeviceModel.product == _NULL_DEVICE_PRODUCT_TYPE |
| ) |
| null_devices = device_query.fetch() |
| existing_null_device_count = len(null_devices) |
| |
| if existing_null_device_count < null_device_count: |
| devices_to_put = [] |
| for _ in range(null_device_count - existing_null_device_count): |
| device = model.DeviceModel() |
| device.hostname = hostname |
| device.serial = "n/a" |
| device.product = _NULL_DEVICE_PRODUCT_TYPE |
| device.status = Status.DEVICE_STATUS_DICT["ready"] |
| device.scheduling_status = Status.DEVICE_SCHEDULING_STATUS_DICT[ |
| "free"] |
| device.timestamp = datetime.datetime.now() |
| devices_to_put.append(device) |
| if devices_to_put: |
| ndb.put_multi(devices_to_put) |
| |
| |
| @endpoints.api(name='host', version='v1') |
| class HostInfoApi(endpoint_base.EndpointBase): |
| """Endpoint API for host_info.""" |
| |
| @endpoints.method( |
| HOST_INFO_RESOURCE, |
| model.DefaultResponse, |
| path='set', |
| http_method='POST', |
| name='set') |
| def set(self, request): |
| """Sets the host info based on the `request`.""" |
| if users.get_current_user(): |
| username = users.get_current_user().email() |
| else: |
| username = "anonymous" |
| |
| devices_to_put = [] |
| for request_device in request.devices: |
| device_query = model.DeviceModel.query( |
| model.DeviceModel.serial == request_device.serial |
| ) |
| existing_device = device_query.fetch() |
| if existing_device: |
| device = existing_device[0] |
| else: |
| device = model.DeviceModel() |
| device.serial = request_device.serial |
| device.scheduling_status = Status.DEVICE_SCHEDULING_STATUS_DICT[ |
| "free"] |
| if not device.product or request_device.product != "error": |
| device.product = request_device.product |
| |
| device.username = username |
| device.hostname = request.hostname |
| device.status = request_device.status |
| device.timestamp = datetime.datetime.now() |
| devices_to_put.append(device) |
| if devices_to_put: |
| ndb.put_multi(devices_to_put) |
| |
| return model.DefaultResponse( |
| return_code=model.ReturnCodeMessage.SUCCESS) |
| |
| @endpoints.method( |
| endpoint_base.GET_REQUEST_RESOURCE, |
| model.DeviceResponseMessage, |
| path="get", |
| http_method="POST", |
| name="get") |
| def get(self, request): |
| """Gets the devices from datastore.""" |
| return_list, more = self.Get(request=request, |
| metaclass=model.DeviceModel, |
| message=model.DeviceInfoMessage) |
| |
| return model.DeviceResponseMessage(devices=return_list, has_next=more) |
| |
| @endpoints.method( |
| endpoint_base.COUNT_REQUEST_RESOURCE, |
| model.CountResponseMessage, |
| path="count", |
| http_method="POST", |
| name="count") |
| def count(self, request): |
| """Gets total number of DeviceModel entities stored in datastore.""" |
| filters = self.CreateFilterList( |
| filter_string=request.filter, metaclass=model.DeviceModel) |
| |
| count = self.Count(metaclass=model.DeviceModel, filters=filters) |
| |
| return model.CountResponseMessage(count=count) |