Skip to content

Commit

Permalink
Merge pull request #2933 from xiaoweim/mock_bigqueryroutine
Browse files Browse the repository at this point in the history
feat: add mockgcp for bigqueryroutine
  • Loading branch information
google-oss-prow[bot] authored Dec 3, 2024
2 parents 7bddc00 + c6fad4a commit 3530c83
Show file tree
Hide file tree
Showing 14 changed files with 1,339 additions and 8 deletions.
1 change: 1 addition & 0 deletions config/tests/samples/create/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ func MaybeSkip(t *testing.T, name string, resources []*unstructured.Unstructured

case schema.GroupKind{Group: "bigquery.cnrm.cloud.google.com", Kind: "BigQueryDataset"}:
case schema.GroupKind{Group: "bigquery.cnrm.cloud.google.com", Kind: "BigQueryTable"}:
case schema.GroupKind{Group: "bigquery.cnrm.cloud.google.com", Kind: "BigQueryRoutine"}:

case schema.GroupKind{Group: "bigqueryanalyticshub.cnrm.cloud.google.com", Kind: "BigQueryAnalyticsHubDataExchange"}:
case schema.GroupKind{Group: "bigqueryanalyticshub.cnrm.cloud.google.com", Kind: "BigQueryAnalyticsHubListing"}:
Expand Down
169 changes: 169 additions & 0 deletions mockgcp/mockbigquery/routine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// Copyright 2024 Google LLC
//
// 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.

package mockbigquery

import (
"context"
"net/http"
"time"

"github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/common/httpmux"
"github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/common/projects"
pb "github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/generated/mockgcp/cloud/bigquery/v2"
"github.com/golang/protobuf/ptypes/empty"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)

var defaultLanguage = "SQL"
var DeterminismLevelUnspecified = "DETERMINISM_LEVEL_UNSPECIFIED"

type routinesServer struct {
*MockService
pb.UnimplementedRoutinesServerServer
}

func (s *routinesServer) GetRoutine(ctx context.Context, req *pb.GetRoutineRequest) (*pb.Routine, error) {
name, err := s.buildRoutineName(req.GetProjectId(), req.GetDatasetId(), req.GetRoutineId())
if err != nil {
return nil, err
}

fqn := name.String()

obj := &pb.Routine{}
if err := s.storage.Get(ctx, fqn, obj); err != nil {
if status.Code(err) == codes.NotFound {
return nil, status.Errorf(codes.NotFound, "Not found: Routine %s:%s.%s", name.Project.ID, name.DatasetID, name.RoutineID)
}
return nil, err
}
if obj.Language == nil {
obj.Language = &defaultLanguage
}
if obj.DeterminismLevel != nil && *obj.DeterminismLevel == DeterminismLevelUnspecified {
obj.DeterminismLevel = nil
}

return obj, nil
}

func (s *routinesServer) InsertRoutine(ctx context.Context, req *pb.InsertRoutineRequest) (*pb.Routine, error) {
name, err := s.buildRoutineName(req.GetProjectId(), req.GetDatasetId(), req.GetRoutine().GetRoutineReference().GetRoutineId())
if err != nil {
return nil, err
}

fqn := name.String()

now := time.Now()

obj := proto.Clone(req.GetRoutine()).(*pb.Routine)

if obj.RoutineReference == nil {
obj.RoutineReference = &pb.RoutineReference{}
}
if obj.GetRoutineReference().ProjectId == nil {
obj.RoutineReference.ProjectId = req.ProjectId
}
obj.CreationTime = PtrTo(now.UnixMilli())
obj.LastModifiedTime = PtrTo(now.UnixMilli())
obj.Etag = PtrTo(computeEtag(obj))

if err := s.storage.Create(ctx, fqn, obj); err != nil {
return nil, status.Errorf(codes.Internal, "error creating routine: %v", err)
}
if obj.Language == nil {
obj.Language = &defaultLanguage
}
if obj.DeterminismLevel != nil && *obj.DeterminismLevel == DeterminismLevelUnspecified {
obj.DeterminismLevel = nil
}
return obj, nil
}

func (s *routinesServer) UpdateRoutine(ctx context.Context, req *pb.UpdateRoutineRequest) (*pb.Routine, error) {
name, err := s.buildRoutineName(req.GetProjectId(), req.GetDatasetId(), req.GetRoutineId())
if err != nil {
return nil, err
}

fqn := name.String()

existing := &pb.Routine{}
if err := s.storage.Get(ctx, fqn, existing); err != nil {
return nil, err
}

now := time.Now()

updated := req.GetRoutine()
updated.RoutineReference = existing.RoutineReference

updated.CreationTime = existing.CreationTime
updated.LastModifiedTime = PtrTo(now.UnixMilli())
updated.RoutineType = existing.RoutineType
updated.Etag = PtrTo(computeEtag(updated))

if err := s.storage.Update(ctx, fqn, updated); err != nil {
return nil, err
}

return updated, err
}

func (s *routinesServer) DeleteRoutine(ctx context.Context, req *pb.DeleteRoutineRequest) (*empty.Empty, error) {
name, err := s.buildRoutineName(req.GetProjectId(), req.GetDatasetId(), req.GetRoutineId())
if err != nil {
return nil, err
}

fqn := name.String()

deleted := &pb.Dataset{}
if err := s.storage.Delete(ctx, fqn, deleted); err != nil {
return nil, err
}

httpmux.SetStatusCode(ctx, http.StatusNoContent)

return &empty.Empty{}, nil
}

type routineName struct {
Project *projects.ProjectData
DatasetID string
RoutineID string
}

func (n *routineName) String() string {
return "projects/" + n.Project.ID + "/datasets/" + n.DatasetID + "/routines/" + n.RoutineID
}

func (s *MockService) buildRoutineName(projectName string, datasetID string, routineID string) (*routineName, error) {
project, err := s.Projects.GetProjectByID(projectName)
if err != nil {
return nil, err
}

name := &routineName{
Project: project,
DatasetID: datasetID,
RoutineID: routineID,
}

return name, nil
}
3 changes: 2 additions & 1 deletion mockgcp/mockbigquery/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ func (s *MockService) ExpectedHosts() []string {
func (s *MockService) Register(grpcServer *grpc.Server) {
pb.RegisterDatasetsServerServer(grpcServer, &datasetsServer{MockService: s})
pb.RegisterTablesServerServer(grpcServer, &tablesServer{MockService: s})
pb.RegisterRoutinesServerServer(grpcServer, &routinesServer{MockService: s})
}

func (s *MockService) NewHTTPMux(ctx context.Context, conn *grpc.ClientConn) (http.Handler, error) {
mux, err := httpmux.NewServeMux(ctx, conn, httpmux.Options{}, pb.RegisterDatasetsServerHandler, pb.RegisterTablesServerHandler)
mux, err := httpmux.NewServeMux(ctx, conn, httpmux.Options{}, pb.RegisterDatasetsServerHandler, pb.RegisterTablesServerHandler, pb.RegisterRoutinesServerHandler)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: bigquery.cnrm.cloud.google.com/v1beta1
kind: BigQueryRoutine
metadata:
annotations:
cnrm.cloud.google.com/management-conflict-prevention-policy: none
cnrm.cloud.google.com/state-into-spec: absent
finalizers:
- cnrm.cloud.google.com/finalizer
- cnrm.cloud.google.com/deletion-defender
generation: 2
labels:
cnrm-test: "true"
name: bigqueryroutine-${uniqueId}
namespace: ${uniqueId}
spec:
datasetRef:
name: bigquerydataset${uniqueId}
definitionBody: CREATE FUNCTION Sub(x FLOAT64, y FLOAT64) RETURNS FLOAT64 AS (x
- y);
projectRef:
external: ${projectId}
resourceID: bigqueryroutine${uniqueId}
routineType: PROCEDURE
status:
conditions:
- lastTransitionTime: "1970-01-01T00:00:00Z"
message: The resource is up to date
reason: UpToDate
status: "True"
type: Ready
creationTime: "1970-01-01T00:00:00Z"
lastModifiedTime: "1970-01-01T00:00:00Z"
observedGeneration: 2
Loading

0 comments on commit 3530c83

Please sign in to comment.