1# Copyright 2017 Google Inc. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Build Info APIs implemented using Google Cloud Endpoints."""
15
16import datetime
17import endpoints
18import logging
19
20from webapp.src.endpoint import endpoint_base
21from webapp.src.proto import model
22
23BUILD_INFO_RESOURCE = endpoints.ResourceContainer(model.BuildInfoMessage)
24
25
26@endpoints.api(name="build", version="v1")
27class BuildInfoApi(endpoint_base.EndpointBase):
28    """Endpoint API for build_info."""
29
30    @endpoints.method(
31        BUILD_INFO_RESOURCE,
32        model.DefaultResponse,
33        path="set",
34        http_method="POST",
35        name="set")
36    def set(self, request):
37        """Sets the build info based on the `request`."""
38        build_query = model.BuildModel.query(
39            model.BuildModel.build_id == request.build_id,
40            model.BuildModel.build_target == request.build_target,
41            model.BuildModel.build_type == request.build_type,
42            model.BuildModel.artifact_type == request.artifact_type)
43        existing_builds = build_query.fetch()
44
45        if existing_builds and len(existing_builds) > 1:
46            logging.warning(
47                "Duplicated builds found for [build_id]{} "
48                "[build_target]{} [build_type]{} [artifact_type]{}".format(
49                    request.build_id, request.build_target, request.build_type,
50                    request.artifact_type))
51
52        if existing_builds:
53            build = existing_builds[0]
54            if request.signed:
55                # only signed builds need to overwrite the exist entities.
56                build.signed = request.signed
57        else:
58            build = model.BuildModel()
59            common_attributes = self.GetCommonAttributes(request,
60                                                         model.BuildModel)
61            for attr in common_attributes:
62                setattr(build, attr, getattr(request, attr))
63
64        build.timestamp = datetime.datetime.now()
65        build.put()
66
67        return model.DefaultResponse(
68            return_code=model.ReturnCodeMessage.SUCCESS)
69
70    @endpoints.method(
71        endpoint_base.GET_REQUEST_RESOURCE,
72        model.BuildResponseMessage,
73        path="get",
74        http_method="POST",
75        name="get")
76    def get(self, request):
77        """Gets the builds from datastore."""
78        return_list, more = self.Get(request=request,
79                                     metaclass=model.BuildModel,
80                                     message=model.BuildInfoMessage)
81        return model.BuildResponseMessage(builds=return_list, has_next=more)
82
83    @endpoints.method(
84        endpoint_base.COUNT_REQUEST_RESOURCE,
85        model.CountResponseMessage,
86        path="count",
87        http_method="POST",
88        name="count")
89    def count(self, request):
90        """Gets total number of BuildModel entities stored in datastore."""
91        filters = self.CreateFilterList(
92            filter_string=request.filter, metaclass=model.BuildModel)
93        count = self.Count(metaclass=model.BuildModel, filters=filters)
94
95        return model.CountResponseMessage(count=count)
96