You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/02/28 02:29:58 UTC
[incubator-servicecomb-service-center] branch master updated: SC-49
Pact broker module for consumer-driven contract testing (#220)
This is an automated email from the ASF dual-hosted git repository.
littlecui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new 47203c7 SC-49 Pact broker module for consumer-driven contract testing (#220)
47203c7 is described below
commit 47203c76d5b4b1b5cb88f1d92374cc2d6ea3c3f4
Author: Ganesha Upadhyaya <ga...@gmail.com>
AuthorDate: Tue Feb 27 20:29:56 2018 -0600
SC-49 Pact broker module for consumer-driven contract testing (#220)
* pact broker implementation as sc module
* fixing bugs
* adding some tests
* updating imports and fixing the cache invoke
* updating the license info
* reverting an unnecessary change
* updating broker to the latest changes and fixing the broken integration test
* updating PR change requests
---
server/bootstrap/bootstrap.go | 3 +
server/broker/README.md | 98 ++++
server/broker/broker.go | 29 ++
server/broker/broker.pb.go | 950 ++++++++++++++++++++++++++++++++++
server/broker/broker.proto | 158 ++++++
server/broker/broker_key_generator.go | 200 +++++++
server/broker/controller.go | 191 +++++++
server/broker/service.go | 874 +++++++++++++++++++++++++++++++
server/broker/service_test.go | 200 +++++++
server/broker/store.go | 156 ++++++
server/broker/util.go | 680 ++++++++++++++++++++++++
server/rest/controller/rest_util.go | 12 +
12 files changed, 3551 insertions(+)
diff --git a/server/bootstrap/bootstrap.go b/server/bootstrap/bootstrap.go
index 058d034..1bd7a5a 100644
--- a/server/bootstrap/bootstrap.go
+++ b/server/bootstrap/bootstrap.go
@@ -45,6 +45,9 @@ import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/i
// module
import _ "github.com/apache/incubator-servicecomb-service-center/server/govern"
+// module
+import _ "github.com/apache/incubator-servicecomb-service-center/server/broker"
+
import (
"github.com/apache/incubator-servicecomb-service-center/pkg/util"
"github.com/apache/incubator-servicecomb-service-center/server/handler/auth"
diff --git a/server/broker/README.md b/server/broker/README.md
new file mode 100644
index 0000000..9f57908
--- /dev/null
+++ b/server/broker/README.md
@@ -0,0 +1,98 @@
+# Pact Broker Module
+
+Pact broker module enables consumer-driven contract testing in service-center.
+
+## Pact broker services
+
+* Consumer microservices can publish pact.
+
+```
+PUT /pacts/provider/:providerId/consumer/:consumerId/version/:number
+'{
+ "provider" : "",
+ "consumer" : "",
+ ...
+
+}'
+```
+
+* Provider microservices can retrieve pacts published by consumer microservices, verify the pacts, and publish the verification results.
+
+ 1. Retrieving the information about the pacts associated with a provider
+
+```
+GET /pacts/provider/:providerId/latest
+
+Response:
+{
+ "_links" : {
+ "pacts" : [
+ {
+ "href" : "/pacts/provider/:providerId/consumer/:consumerId/version/:number"
+ "name" : "Pact between consumerId and providerId with version number"
+ }
+ ]
+ }
+}
+```
+
+ 2. Retrieving the actual pact between a consumer and provider for verification
+
+```
+GET /pacts/provider/:providerId/consumer/:consumerId/version/:number
+Response:
+{
+ "pact" : []byte
+}
+```
+
+ 3. Publishing the pact verification result to the broker
+
+```
+POST /pacts/provider/:providerId/consumer/:consumerId/pact-version/:number/verification-results
+'{
+ "success" : true
+ "providerApplicationVersion" : "0.0.1"
+}'
+
+Response:
+{
+ "confirmation" : {
+ "providerName" : ""
+ "providerApplicationVersion" : "0.0.1"
+ "success" : true
+ "verificationDate" : ""
+ }
+}
+```
+
+* Consumer microservices can retrieve the verification results published by the providers.
+
+```
+GET /verification-results/consumer/:consumerId/version/:version/latest
+
+Response:
+{
+ "result" : {
+ "success" : true
+ "providerSummary" : {
+ "successful" : [
+ ]
+ "failed" : [
+ ]
+ "unknown" : [
+ ]
+ }
+ "_embedded" : {
+ "verificationResults" : [
+ {
+ "providerName" : ""
+ "providerApplicationVersion" : ""
+ "success" : true
+ "verificationDate" : ""
+ }
+ ]
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/server/broker/broker.go b/server/broker/broker.go
new file mode 100644
index 0000000..fc807be
--- /dev/null
+++ b/server/broker/broker.go
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ roa "github.com/apache/incubator-servicecomb-service-center/pkg/rest"
+)
+
+func init() {
+ registerREST()
+}
+
+func registerREST() {
+ roa.RegisterServent(&BrokerController{})
+}
diff --git a/server/broker/broker.pb.go b/server/broker/broker.pb.go
new file mode 100644
index 0000000..0dffd1c
--- /dev/null
+++ b/server/broker/broker.pb.go
@@ -0,0 +1,950 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: server/broker/broker.proto
+
+/*
+Package broker is a generated protocol buffer package.
+
+It is generated from these files:
+ server/broker/broker.proto
+
+It has these top-level messages:
+ Participant
+ Version
+ Pact
+ PactVersion
+ Tag
+ PublishPactRequest
+ PublishPactResponse
+ GetAllProviderPactsRequest
+ ConsumerInfo
+ Links
+ GetAllProviderPactsResponse
+ GetProviderConsumerVersionPactRequest
+ GetProviderConsumerVersionPactResponse
+ Verification
+ VerificationSummary
+ VerificationDetail
+ VerificationDetails
+ VerificationResult
+ PublishVerificationRequest
+ PublishVerificationResponse
+ RetrieveVerificationRequest
+ RetrieveVerificationResponse
+ BaseBrokerRequest
+ BrokerAPIInfoEntry
+ BrokerHomeResponse
+*/
+package broker
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import services "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Participant struct {
+ Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
+ AppId string `protobuf:"bytes,2,opt,name=appId" json:"appId,omitempty"`
+ ServiceName string `protobuf:"bytes,3,opt,name=serviceName" json:"serviceName,omitempty"`
+}
+
+func (m *Participant) Reset() { *m = Participant{} }
+func (m *Participant) String() string { return proto.CompactTextString(m) }
+func (*Participant) ProtoMessage() {}
+func (*Participant) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Participant) GetId() int32 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *Participant) GetAppId() string {
+ if m != nil {
+ return m.AppId
+ }
+ return ""
+}
+
+func (m *Participant) GetServiceName() string {
+ if m != nil {
+ return m.ServiceName
+ }
+ return ""
+}
+
+type Version struct {
+ Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
+ Number string `protobuf:"bytes,2,opt,name=number" json:"number,omitempty"`
+ ParticipantId int32 `protobuf:"varint,3,opt,name=participantId" json:"participantId,omitempty"`
+ Order int32 `protobuf:"varint,4,opt,name=order" json:"order,omitempty"`
+}
+
+func (m *Version) Reset() { *m = Version{} }
+func (m *Version) String() string { return proto.CompactTextString(m) }
+func (*Version) ProtoMessage() {}
+func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+func (m *Version) GetId() int32 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *Version) GetNumber() string {
+ if m != nil {
+ return m.Number
+ }
+ return ""
+}
+
+func (m *Version) GetParticipantId() int32 {
+ if m != nil {
+ return m.ParticipantId
+ }
+ return 0
+}
+
+func (m *Version) GetOrder() int32 {
+ if m != nil {
+ return m.Order
+ }
+ return 0
+}
+
+type Pact struct {
+ Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
+ ConsumerParticipantId int32 `protobuf:"varint,2,opt,name=consumerParticipantId" json:"consumerParticipantId,omitempty"`
+ ProviderParticipantId int32 `protobuf:"varint,3,opt,name=providerParticipantId" json:"providerParticipantId,omitempty"`
+ Sha []byte `protobuf:"bytes,4,opt,name=sha,proto3" json:"sha,omitempty"`
+ Content []byte `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
+}
+
+func (m *Pact) Reset() { *m = Pact{} }
+func (m *Pact) String() string { return proto.CompactTextString(m) }
+func (*Pact) ProtoMessage() {}
+func (*Pact) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *Pact) GetId() int32 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *Pact) GetConsumerParticipantId() int32 {
+ if m != nil {
+ return m.ConsumerParticipantId
+ }
+ return 0
+}
+
+func (m *Pact) GetProviderParticipantId() int32 {
+ if m != nil {
+ return m.ProviderParticipantId
+ }
+ return 0
+}
+
+func (m *Pact) GetSha() []byte {
+ if m != nil {
+ return m.Sha
+ }
+ return nil
+}
+
+func (m *Pact) GetContent() []byte {
+ if m != nil {
+ return m.Content
+ }
+ return nil
+}
+
+type PactVersion struct {
+ Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
+ VersionId int32 `protobuf:"varint,2,opt,name=versionId" json:"versionId,omitempty"`
+ PactId int32 `protobuf:"varint,3,opt,name=pactId" json:"pactId,omitempty"`
+ ProviderParticipantId int32 `protobuf:"varint,4,opt,name=providerParticipantId" json:"providerParticipantId,omitempty"`
+}
+
+func (m *PactVersion) Reset() { *m = PactVersion{} }
+func (m *PactVersion) String() string { return proto.CompactTextString(m) }
+func (*PactVersion) ProtoMessage() {}
+func (*PactVersion) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+
+func (m *PactVersion) GetId() int32 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *PactVersion) GetVersionId() int32 {
+ if m != nil {
+ return m.VersionId
+ }
+ return 0
+}
+
+func (m *PactVersion) GetPactId() int32 {
+ if m != nil {
+ return m.PactId
+ }
+ return 0
+}
+
+func (m *PactVersion) GetProviderParticipantId() int32 {
+ if m != nil {
+ return m.ProviderParticipantId
+ }
+ return 0
+}
+
+type Tag struct {
+ Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ VersionId int32 `protobuf:"varint,2,opt,name=versionId" json:"versionId,omitempty"`
+}
+
+func (m *Tag) Reset() { *m = Tag{} }
+func (m *Tag) String() string { return proto.CompactTextString(m) }
+func (*Tag) ProtoMessage() {}
+func (*Tag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+
+func (m *Tag) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *Tag) GetVersionId() int32 {
+ if m != nil {
+ return m.VersionId
+ }
+ return 0
+}
+
+type PublishPactRequest struct {
+ ProviderId string `protobuf:"bytes,1,opt,name=providerId" json:"providerId,omitempty"`
+ ConsumerId string `protobuf:"bytes,2,opt,name=consumerId" json:"consumerId,omitempty"`
+ Version string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
+ Pact []byte `protobuf:"bytes,4,opt,name=pact,proto3" json:"pact,omitempty"`
+}
+
+func (m *PublishPactRequest) Reset() { *m = PublishPactRequest{} }
+func (m *PublishPactRequest) String() string { return proto.CompactTextString(m) }
+func (*PublishPactRequest) ProtoMessage() {}
+func (*PublishPactRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
+
+func (m *PublishPactRequest) GetProviderId() string {
+ if m != nil {
+ return m.ProviderId
+ }
+ return ""
+}
+
+func (m *PublishPactRequest) GetConsumerId() string {
+ if m != nil {
+ return m.ConsumerId
+ }
+ return ""
+}
+
+func (m *PublishPactRequest) GetVersion() string {
+ if m != nil {
+ return m.Version
+ }
+ return ""
+}
+
+func (m *PublishPactRequest) GetPact() []byte {
+ if m != nil {
+ return m.Pact
+ }
+ return nil
+}
+
+type PublishPactResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+}
+
+func (m *PublishPactResponse) Reset() { *m = PublishPactResponse{} }
+func (m *PublishPactResponse) String() string { return proto.CompactTextString(m) }
+func (*PublishPactResponse) ProtoMessage() {}
+func (*PublishPactResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
+
+func (m *PublishPactResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+type GetAllProviderPactsRequest struct {
+ ProviderId string `protobuf:"bytes,1,opt,name=providerId" json:"providerId,omitempty"`
+ BaseUrl *BaseBrokerRequest `protobuf:"bytes,2,opt,name=baseUrl" json:"baseUrl,omitempty"`
+}
+
+func (m *GetAllProviderPactsRequest) Reset() { *m = GetAllProviderPactsRequest{} }
+func (m *GetAllProviderPactsRequest) String() string { return proto.CompactTextString(m) }
+func (*GetAllProviderPactsRequest) ProtoMessage() {}
+func (*GetAllProviderPactsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
+
+func (m *GetAllProviderPactsRequest) GetProviderId() string {
+ if m != nil {
+ return m.ProviderId
+ }
+ return ""
+}
+
+func (m *GetAllProviderPactsRequest) GetBaseUrl() *BaseBrokerRequest {
+ if m != nil {
+ return m.BaseUrl
+ }
+ return nil
+}
+
+type ConsumerInfo struct {
+ Href string `protobuf:"bytes,1,opt,name=href" json:"href,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+}
+
+func (m *ConsumerInfo) Reset() { *m = ConsumerInfo{} }
+func (m *ConsumerInfo) String() string { return proto.CompactTextString(m) }
+func (*ConsumerInfo) ProtoMessage() {}
+func (*ConsumerInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+
+func (m *ConsumerInfo) GetHref() string {
+ if m != nil {
+ return m.Href
+ }
+ return ""
+}
+
+func (m *ConsumerInfo) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+type Links struct {
+ Pacts []*ConsumerInfo `protobuf:"bytes,1,rep,name=pacts" json:"pacts,omitempty"`
+}
+
+func (m *Links) Reset() { *m = Links{} }
+func (m *Links) String() string { return proto.CompactTextString(m) }
+func (*Links) ProtoMessage() {}
+func (*Links) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
+
+func (m *Links) GetPacts() []*ConsumerInfo {
+ if m != nil {
+ return m.Pacts
+ }
+ return nil
+}
+
+type GetAllProviderPactsResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ XLinks *Links `protobuf:"bytes,2,opt,name=_links,json=Links" json:"_links,omitempty"`
+}
+
+func (m *GetAllProviderPactsResponse) Reset() { *m = GetAllProviderPactsResponse{} }
+func (m *GetAllProviderPactsResponse) String() string { return proto.CompactTextString(m) }
+func (*GetAllProviderPactsResponse) ProtoMessage() {}
+func (*GetAllProviderPactsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
+
+func (m *GetAllProviderPactsResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *GetAllProviderPactsResponse) GetXLinks() *Links {
+ if m != nil {
+ return m.XLinks
+ }
+ return nil
+}
+
+type GetProviderConsumerVersionPactRequest struct {
+ ProviderId string `protobuf:"bytes,1,opt,name=providerId" json:"providerId,omitempty"`
+ ConsumerId string `protobuf:"bytes,2,opt,name=consumerId" json:"consumerId,omitempty"`
+ Version string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
+ BaseUrl *BaseBrokerRequest `protobuf:"bytes,4,opt,name=baseUrl" json:"baseUrl,omitempty"`
+}
+
+func (m *GetProviderConsumerVersionPactRequest) Reset() { *m = GetProviderConsumerVersionPactRequest{} }
+func (m *GetProviderConsumerVersionPactRequest) String() string { return proto.CompactTextString(m) }
+func (*GetProviderConsumerVersionPactRequest) ProtoMessage() {}
+func (*GetProviderConsumerVersionPactRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor0, []int{11}
+}
+
+func (m *GetProviderConsumerVersionPactRequest) GetProviderId() string {
+ if m != nil {
+ return m.ProviderId
+ }
+ return ""
+}
+
+func (m *GetProviderConsumerVersionPactRequest) GetConsumerId() string {
+ if m != nil {
+ return m.ConsumerId
+ }
+ return ""
+}
+
+func (m *GetProviderConsumerVersionPactRequest) GetVersion() string {
+ if m != nil {
+ return m.Version
+ }
+ return ""
+}
+
+func (m *GetProviderConsumerVersionPactRequest) GetBaseUrl() *BaseBrokerRequest {
+ if m != nil {
+ return m.BaseUrl
+ }
+ return nil
+}
+
+type GetProviderConsumerVersionPactResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ Pact []byte `protobuf:"bytes,2,opt,name=pact,proto3" json:"pact,omitempty"`
+}
+
+func (m *GetProviderConsumerVersionPactResponse) Reset() {
+ *m = GetProviderConsumerVersionPactResponse{}
+}
+func (m *GetProviderConsumerVersionPactResponse) String() string { return proto.CompactTextString(m) }
+func (*GetProviderConsumerVersionPactResponse) ProtoMessage() {}
+func (*GetProviderConsumerVersionPactResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor0, []int{12}
+}
+
+func (m *GetProviderConsumerVersionPactResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *GetProviderConsumerVersionPactResponse) GetPact() []byte {
+ if m != nil {
+ return m.Pact
+ }
+ return nil
+}
+
+type Verification struct {
+ Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
+ Number int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"`
+ PactVersionId int32 `protobuf:"varint,3,opt,name=pactVersionId" json:"pactVersionId,omitempty"`
+ Success bool `protobuf:"varint,4,opt,name=success" json:"success,omitempty"`
+ ProviderVersion string `protobuf:"bytes,5,opt,name=providerVersion" json:"providerVersion,omitempty"`
+ BuildUrl string `protobuf:"bytes,6,opt,name=buildUrl" json:"buildUrl,omitempty"`
+ VerificationDate string `protobuf:"bytes,7,opt,name=verificationDate" json:"verificationDate,omitempty"`
+}
+
+func (m *Verification) Reset() { *m = Verification{} }
+func (m *Verification) String() string { return proto.CompactTextString(m) }
+func (*Verification) ProtoMessage() {}
+func (*Verification) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
+
+func (m *Verification) GetId() int32 {
+ if m != nil {
+ return m.Id
+ }
+ return 0
+}
+
+func (m *Verification) GetNumber() int32 {
+ if m != nil {
+ return m.Number
+ }
+ return 0
+}
+
+func (m *Verification) GetPactVersionId() int32 {
+ if m != nil {
+ return m.PactVersionId
+ }
+ return 0
+}
+
+func (m *Verification) GetSuccess() bool {
+ if m != nil {
+ return m.Success
+ }
+ return false
+}
+
+func (m *Verification) GetProviderVersion() string {
+ if m != nil {
+ return m.ProviderVersion
+ }
+ return ""
+}
+
+func (m *Verification) GetBuildUrl() string {
+ if m != nil {
+ return m.BuildUrl
+ }
+ return ""
+}
+
+func (m *Verification) GetVerificationDate() string {
+ if m != nil {
+ return m.VerificationDate
+ }
+ return ""
+}
+
+type VerificationSummary struct {
+ Successful []string `protobuf:"bytes,1,rep,name=successful" json:"successful,omitempty"`
+ Failed []string `protobuf:"bytes,2,rep,name=failed" json:"failed,omitempty"`
+ Unknown []string `protobuf:"bytes,3,rep,name=unknown" json:"unknown,omitempty"`
+}
+
+func (m *VerificationSummary) Reset() { *m = VerificationSummary{} }
+func (m *VerificationSummary) String() string { return proto.CompactTextString(m) }
+func (*VerificationSummary) ProtoMessage() {}
+func (*VerificationSummary) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
+
+func (m *VerificationSummary) GetSuccessful() []string {
+ if m != nil {
+ return m.Successful
+ }
+ return nil
+}
+
+func (m *VerificationSummary) GetFailed() []string {
+ if m != nil {
+ return m.Failed
+ }
+ return nil
+}
+
+func (m *VerificationSummary) GetUnknown() []string {
+ if m != nil {
+ return m.Unknown
+ }
+ return nil
+}
+
+type VerificationDetail struct {
+ ProviderName string `protobuf:"bytes,1,opt,name=providerName" json:"providerName,omitempty"`
+ ProviderApplicationVersion string `protobuf:"bytes,2,opt,name=providerApplicationVersion" json:"providerApplicationVersion,omitempty"`
+ Success bool `protobuf:"varint,3,opt,name=success" json:"success,omitempty"`
+ VerificationDate string `protobuf:"bytes,4,opt,name=verificationDate" json:"verificationDate,omitempty"`
+}
+
+func (m *VerificationDetail) Reset() { *m = VerificationDetail{} }
+func (m *VerificationDetail) String() string { return proto.CompactTextString(m) }
+func (*VerificationDetail) ProtoMessage() {}
+func (*VerificationDetail) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
+
+func (m *VerificationDetail) GetProviderName() string {
+ if m != nil {
+ return m.ProviderName
+ }
+ return ""
+}
+
+func (m *VerificationDetail) GetProviderApplicationVersion() string {
+ if m != nil {
+ return m.ProviderApplicationVersion
+ }
+ return ""
+}
+
+func (m *VerificationDetail) GetSuccess() bool {
+ if m != nil {
+ return m.Success
+ }
+ return false
+}
+
+func (m *VerificationDetail) GetVerificationDate() string {
+ if m != nil {
+ return m.VerificationDate
+ }
+ return ""
+}
+
+type VerificationDetails struct {
+ VerificationResults []*VerificationDetail `protobuf:"bytes,1,rep,name=verificationResults" json:"verificationResults,omitempty"`
+}
+
+func (m *VerificationDetails) Reset() { *m = VerificationDetails{} }
+func (m *VerificationDetails) String() string { return proto.CompactTextString(m) }
+func (*VerificationDetails) ProtoMessage() {}
+func (*VerificationDetails) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
+
+func (m *VerificationDetails) GetVerificationResults() []*VerificationDetail {
+ if m != nil {
+ return m.VerificationResults
+ }
+ return nil
+}
+
+type VerificationResult struct {
+ Success bool `protobuf:"varint,1,opt,name=success" json:"success,omitempty"`
+ ProviderSummary *VerificationSummary `protobuf:"bytes,2,opt,name=providerSummary" json:"providerSummary,omitempty"`
+ XEmbedded *VerificationDetails `protobuf:"bytes,3,opt,name=_embedded,json=Embedded" json:"_embedded,omitempty"`
+}
+
+func (m *VerificationResult) Reset() { *m = VerificationResult{} }
+func (m *VerificationResult) String() string { return proto.CompactTextString(m) }
+func (*VerificationResult) ProtoMessage() {}
+func (*VerificationResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
+
+func (m *VerificationResult) GetSuccess() bool {
+ if m != nil {
+ return m.Success
+ }
+ return false
+}
+
+func (m *VerificationResult) GetProviderSummary() *VerificationSummary {
+ if m != nil {
+ return m.ProviderSummary
+ }
+ return nil
+}
+
+func (m *VerificationResult) GetXEmbedded() *VerificationDetails {
+ if m != nil {
+ return m.XEmbedded
+ }
+ return nil
+}
+
+type PublishVerificationRequest struct {
+ ProviderId string `protobuf:"bytes,1,opt,name=providerId" json:"providerId,omitempty"`
+ ConsumerId string `protobuf:"bytes,2,opt,name=consumerId" json:"consumerId,omitempty"`
+ PactId int32 `protobuf:"varint,3,opt,name=pactId" json:"pactId,omitempty"`
+ Success bool `protobuf:"varint,4,opt,name=success" json:"success,omitempty"`
+ ProviderApplicationVersion string `protobuf:"bytes,5,opt,name=providerApplicationVersion" json:"providerApplicationVersion,omitempty"`
+}
+
+func (m *PublishVerificationRequest) Reset() { *m = PublishVerificationRequest{} }
+func (m *PublishVerificationRequest) String() string { return proto.CompactTextString(m) }
+func (*PublishVerificationRequest) ProtoMessage() {}
+func (*PublishVerificationRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
+
+func (m *PublishVerificationRequest) GetProviderId() string {
+ if m != nil {
+ return m.ProviderId
+ }
+ return ""
+}
+
+func (m *PublishVerificationRequest) GetConsumerId() string {
+ if m != nil {
+ return m.ConsumerId
+ }
+ return ""
+}
+
+func (m *PublishVerificationRequest) GetPactId() int32 {
+ if m != nil {
+ return m.PactId
+ }
+ return 0
+}
+
+func (m *PublishVerificationRequest) GetSuccess() bool {
+ if m != nil {
+ return m.Success
+ }
+ return false
+}
+
+func (m *PublishVerificationRequest) GetProviderApplicationVersion() string {
+ if m != nil {
+ return m.ProviderApplicationVersion
+ }
+ return ""
+}
+
+type PublishVerificationResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ Confirmation *VerificationDetail `protobuf:"bytes,2,opt,name=confirmation" json:"confirmation,omitempty"`
+}
+
+func (m *PublishVerificationResponse) Reset() { *m = PublishVerificationResponse{} }
+func (m *PublishVerificationResponse) String() string { return proto.CompactTextString(m) }
+func (*PublishVerificationResponse) ProtoMessage() {}
+func (*PublishVerificationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
+
+func (m *PublishVerificationResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *PublishVerificationResponse) GetConfirmation() *VerificationDetail {
+ if m != nil {
+ return m.Confirmation
+ }
+ return nil
+}
+
+type RetrieveVerificationRequest struct {
+ ConsumerId string `protobuf:"bytes,1,opt,name=consumerId" json:"consumerId,omitempty"`
+ ConsumerVersion string `protobuf:"bytes,2,opt,name=consumerVersion" json:"consumerVersion,omitempty"`
+}
+
+func (m *RetrieveVerificationRequest) Reset() { *m = RetrieveVerificationRequest{} }
+func (m *RetrieveVerificationRequest) String() string { return proto.CompactTextString(m) }
+func (*RetrieveVerificationRequest) ProtoMessage() {}
+func (*RetrieveVerificationRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
+
+func (m *RetrieveVerificationRequest) GetConsumerId() string {
+ if m != nil {
+ return m.ConsumerId
+ }
+ return ""
+}
+
+func (m *RetrieveVerificationRequest) GetConsumerVersion() string {
+ if m != nil {
+ return m.ConsumerVersion
+ }
+ return ""
+}
+
+type RetrieveVerificationResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ Result *VerificationResult `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
+}
+
+func (m *RetrieveVerificationResponse) Reset() { *m = RetrieveVerificationResponse{} }
+func (m *RetrieveVerificationResponse) String() string { return proto.CompactTextString(m) }
+func (*RetrieveVerificationResponse) ProtoMessage() {}
+func (*RetrieveVerificationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
+
+func (m *RetrieveVerificationResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *RetrieveVerificationResponse) GetResult() *VerificationResult {
+ if m != nil {
+ return m.Result
+ }
+ return nil
+}
+
+type BaseBrokerRequest struct {
+ HostAddress string `protobuf:"bytes,1,opt,name=hostAddress" json:"hostAddress,omitempty"`
+ Scheme string `protobuf:"bytes,2,opt,name=scheme" json:"scheme,omitempty"`
+}
+
+func (m *BaseBrokerRequest) Reset() { *m = BaseBrokerRequest{} }
+func (m *BaseBrokerRequest) String() string { return proto.CompactTextString(m) }
+func (*BaseBrokerRequest) ProtoMessage() {}
+func (*BaseBrokerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
+
+func (m *BaseBrokerRequest) GetHostAddress() string {
+ if m != nil {
+ return m.HostAddress
+ }
+ return ""
+}
+
+func (m *BaseBrokerRequest) GetScheme() string {
+ if m != nil {
+ return m.Scheme
+ }
+ return ""
+}
+
+type BrokerAPIInfoEntry struct {
+ Href string `protobuf:"bytes,1,opt,name=href" json:"href,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+ Title string `protobuf:"bytes,3,opt,name=title" json:"title,omitempty"`
+ Templated bool `protobuf:"varint,4,opt,name=templated" json:"templated,omitempty"`
+}
+
+func (m *BrokerAPIInfoEntry) Reset() { *m = BrokerAPIInfoEntry{} }
+func (m *BrokerAPIInfoEntry) String() string { return proto.CompactTextString(m) }
+func (*BrokerAPIInfoEntry) ProtoMessage() {}
+func (*BrokerAPIInfoEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
+
+func (m *BrokerAPIInfoEntry) GetHref() string {
+ if m != nil {
+ return m.Href
+ }
+ return ""
+}
+
+func (m *BrokerAPIInfoEntry) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *BrokerAPIInfoEntry) GetTitle() string {
+ if m != nil {
+ return m.Title
+ }
+ return ""
+}
+
+func (m *BrokerAPIInfoEntry) GetTemplated() bool {
+ if m != nil {
+ return m.Templated
+ }
+ return false
+}
+
+type BrokerHomeResponse struct {
+ Response *services.Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
+ XLinks map[string]*BrokerAPIInfoEntry `protobuf:"bytes,2,rep,name=_links,json=Links" json:"_links,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+ Curies []*BrokerAPIInfoEntry `protobuf:"bytes,3,rep,name=curies" json:"curies,omitempty"`
+}
+
+func (m *BrokerHomeResponse) Reset() { *m = BrokerHomeResponse{} }
+func (m *BrokerHomeResponse) String() string { return proto.CompactTextString(m) }
+func (*BrokerHomeResponse) ProtoMessage() {}
+func (*BrokerHomeResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
+
+func (m *BrokerHomeResponse) GetResponse() *services.Response {
+ if m != nil {
+ return m.Response
+ }
+ return nil
+}
+
+func (m *BrokerHomeResponse) GetXLinks() map[string]*BrokerAPIInfoEntry {
+ if m != nil {
+ return m.XLinks
+ }
+ return nil
+}
+
+func (m *BrokerHomeResponse) GetCuries() []*BrokerAPIInfoEntry {
+ if m != nil {
+ return m.Curies
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*Participant)(nil), "Participant")
+ proto.RegisterType((*Version)(nil), "Version")
+ proto.RegisterType((*Pact)(nil), "Pact")
+ proto.RegisterType((*PactVersion)(nil), "PactVersion")
+ proto.RegisterType((*Tag)(nil), "Tag")
+ proto.RegisterType((*PublishPactRequest)(nil), "PublishPactRequest")
+ proto.RegisterType((*PublishPactResponse)(nil), "PublishPactResponse")
+ proto.RegisterType((*GetAllProviderPactsRequest)(nil), "GetAllProviderPactsRequest")
+ proto.RegisterType((*ConsumerInfo)(nil), "ConsumerInfo")
+ proto.RegisterType((*Links)(nil), "Links")
+ proto.RegisterType((*GetAllProviderPactsResponse)(nil), "GetAllProviderPactsResponse")
+ proto.RegisterType((*GetProviderConsumerVersionPactRequest)(nil), "GetProviderConsumerVersionPactRequest")
+ proto.RegisterType((*GetProviderConsumerVersionPactResponse)(nil), "GetProviderConsumerVersionPactResponse")
+ proto.RegisterType((*Verification)(nil), "Verification")
+ proto.RegisterType((*VerificationSummary)(nil), "VerificationSummary")
+ proto.RegisterType((*VerificationDetail)(nil), "VerificationDetail")
+ proto.RegisterType((*VerificationDetails)(nil), "VerificationDetails")
+ proto.RegisterType((*VerificationResult)(nil), "VerificationResult")
+ proto.RegisterType((*PublishVerificationRequest)(nil), "PublishVerificationRequest")
+ proto.RegisterType((*PublishVerificationResponse)(nil), "PublishVerificationResponse")
+ proto.RegisterType((*RetrieveVerificationRequest)(nil), "RetrieveVerificationRequest")
+ proto.RegisterType((*RetrieveVerificationResponse)(nil), "RetrieveVerificationResponse")
+ proto.RegisterType((*BaseBrokerRequest)(nil), "BaseBrokerRequest")
+ proto.RegisterType((*BrokerAPIInfoEntry)(nil), "BrokerAPIInfoEntry")
+ proto.RegisterType((*BrokerHomeResponse)(nil), "BrokerHomeResponse")
+}
+
+func init() { proto.RegisterFile("server/broker/broker.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+ // 1037 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xdd, 0x8e, 0x1b, 0x35,
+ 0x14, 0xd6, 0x64, 0x93, 0x6c, 0x72, 0x92, 0xd2, 0xe2, 0x2d, 0x28, 0x4a, 0x4b, 0x15, 0x19, 0x8a,
+ 0x02, 0x54, 0x59, 0xb1, 0xfc, 0x14, 0x21, 0x54, 0x69, 0x97, 0xae, 0xca, 0x4a, 0xb4, 0x8a, 0x0c,
+ 0xed, 0x05, 0x42, 0xaa, 0x26, 0x33, 0x27, 0x9b, 0x61, 0xe7, 0x0f, 0xdb, 0x13, 0xb4, 0x17, 0xdc,
+ 0x70, 0xc7, 0x63, 0xf0, 0x02, 0xf0, 0x06, 0x3c, 0x02, 0xcf, 0xc1, 0x15, 0xcf, 0x80, 0xec, 0xb1,
+ 0x27, 0x33, 0xc9, 0x64, 0xb7, 0x91, 0x10, 0x57, 0xf1, 0xf9, 0xf1, 0xf1, 0x77, 0xbe, 0x73, 0xe6,
+ 0xd8, 0x81, 0xa1, 0x40, 0xbe, 0x44, 0x7e, 0x38, 0xe3, 0xc9, 0x45, 0xf1, 0x33, 0x49, 0x79, 0x22,
+ 0x93, 0xe1, 0xc8, 0xd8, 0xbc, 0x84, 0xe3, 0xa1, 0x56, 0x1d, 0x2a, 0x4d, 0xe0, 0xa1, 0xc8, 0x3d,
+ 0xe8, 0x73, 0xe8, 0x4d, 0x5d, 0x2e, 0x03, 0x2f, 0x48, 0xdd, 0x58, 0x92, 0xd7, 0xa0, 0x11, 0xf8,
+ 0x03, 0x67, 0xe4, 0x8c, 0x5b, 0xac, 0x11, 0xf8, 0xe4, 0x36, 0xb4, 0xdc, 0x34, 0x3d, 0xf3, 0x07,
+ 0x8d, 0x91, 0x33, 0xee, 0xb2, 0x5c, 0x20, 0x23, 0xe8, 0x99, 0x30, 0xcf, 0xdc, 0x08, 0x07, 0x7b,
+ 0xda, 0x56, 0x56, 0xd1, 0x08, 0xf6, 0x5f, 0x20, 0x17, 0x41, 0x12, 0x6f, 0x84, 0x7c, 0x13, 0xda,
+ 0x71, 0x16, 0xcd, 0x90, 0x9b, 0x98, 0x46, 0x22, 0xef, 0xc0, 0x8d, 0x74, 0x85, 0xe4, 0xcc, 0xd7,
+ 0x61, 0x5b, 0xac, 0xaa, 0x54, 0x80, 0x12, 0xee, 0x23, 0x1f, 0x34, 0xb5, 0x35, 0x17, 0xe8, 0xef,
+ 0x0e, 0x34, 0xa7, 0xae, 0xb7, 0x89, 0xff, 0x63, 0x78, 0xc3, 0x4b, 0x62, 0x91, 0x45, 0xc8, 0xa7,
+ 0x95, 0xe0, 0x0d, 0xed, 0x52, 0x6f, 0x54, 0xbb, 0x52, 0x9e, 0x2c, 0x03, 0x7f, 0x7d, 0x57, 0x0e,
+ 0xa9, 0xde, 0x48, 0x6e, 0xc1, 0x9e, 0x58, 0xb8, 0x1a, 0x58, 0x9f, 0xa9, 0x25, 0x19, 0xc0, 0xbe,
+ 0x97, 0xc4, 0x12, 0x63, 0x39, 0x68, 0x69, 0xad, 0x15, 0xe9, 0xaf, 0x8e, 0xe2, 0xdd, 0x93, 0xdb,
+ 0x48, 0xba, 0x0b, 0xdd, 0x65, 0x6e, 0x2a, 0xb0, 0xae, 0x14, 0x8a, 0xc2, 0xd4, 0xf5, 0x56, 0x80,
+ 0x8c, 0xb4, 0x1d, 0x77, 0xf3, 0x0a, 0xdc, 0xf4, 0x21, 0xec, 0x7d, 0xeb, 0x9e, 0x13, 0x02, 0xcd,
+ 0x58, 0x55, 0xd3, 0xd1, 0x55, 0xd1, 0xeb, 0xab, 0x61, 0xd0, 0x5f, 0x1c, 0x20, 0xd3, 0x6c, 0x16,
+ 0x06, 0x62, 0xa1, 0x72, 0x61, 0xf8, 0x63, 0x86, 0x42, 0x92, 0x7b, 0x00, 0xf6, 0xa0, 0x33, 0xdf,
+ 0x84, 0x2b, 0x69, 0x94, 0xdd, 0xd2, 0x5e, 0x34, 0x56, 0x49, 0xa3, 0x58, 0x33, 0x67, 0x98, 0xce,
+ 0xb2, 0xa2, 0x82, 0xa8, 0x32, 0x35, 0x14, 0xeb, 0x35, 0xfd, 0x02, 0x0e, 0x2a, 0x18, 0x44, 0x9a,
+ 0xc4, 0x02, 0xc9, 0x7d, 0xe8, 0x70, 0xb3, 0xd6, 0x10, 0x7a, 0x47, 0xdd, 0x89, 0x35, 0xb2, 0xc2,
+ 0x44, 0x7f, 0x80, 0xe1, 0x13, 0x94, 0xc7, 0x61, 0x38, 0x2d, 0xa8, 0xf1, 0xa4, 0x78, 0xd5, 0x4c,
+ 0x1e, 0xc0, 0xfe, 0xcc, 0x15, 0xf8, 0x9c, 0x87, 0x3a, 0x8d, 0xde, 0x11, 0x99, 0x9c, 0xb8, 0x02,
+ 0x4f, 0xf4, 0x27, 0x68, 0x82, 0x30, 0xeb, 0x42, 0x3f, 0x85, 0xfe, 0x97, 0x36, 0xcb, 0x78, 0x9e,
+ 0xa8, 0x6c, 0x16, 0x1c, 0xe7, 0x96, 0x70, 0xb5, 0x2e, 0x8a, 0xd0, 0x58, 0x15, 0x81, 0x3e, 0x80,
+ 0xd6, 0xd7, 0x41, 0x7c, 0x21, 0xc8, 0xdb, 0xd0, 0x52, 0x29, 0x8b, 0x81, 0x33, 0xda, 0x1b, 0xf7,
+ 0x8e, 0x6e, 0x4c, 0xca, 0xe1, 0x58, 0x6e, 0xa3, 0x1e, 0xdc, 0xa9, 0xcd, 0x68, 0x27, 0x5e, 0xc8,
+ 0x5b, 0xd0, 0x7e, 0x19, 0xaa, 0x43, 0x4d, 0x62, 0xed, 0x89, 0x86, 0xc0, 0x72, 0x24, 0xf4, 0x0f,
+ 0x07, 0xee, 0x3f, 0x41, 0x69, 0x8f, 0xb0, 0x38, 0x4c, 0x37, 0xff, 0x3f, 0xcd, 0x50, 0x22, 0xbf,
+ 0x79, 0x3d, 0xf9, 0x1e, 0xbc, 0x7b, 0x1d, 0xe0, 0xdd, 0x18, 0xb2, 0xbd, 0xd8, 0x28, 0xf5, 0xe2,
+ 0xdf, 0x0e, 0xf4, 0x5f, 0x20, 0x0f, 0xe6, 0x81, 0xe7, 0xca, 0xeb, 0x67, 0x5f, 0xab, 0x3a, 0xfb,
+ 0x8a, 0x69, 0x50, 0x9e, 0x7d, 0x25, 0xa5, 0xe2, 0x42, 0x64, 0x9e, 0x87, 0x42, 0xe8, 0x8c, 0x3b,
+ 0xcc, 0x8a, 0x64, 0x0c, 0x37, 0x2d, 0xa7, 0xc6, 0x5d, 0x0f, 0x9c, 0x2e, 0x5b, 0x57, 0x93, 0x21,
+ 0x74, 0x66, 0x59, 0x10, 0xfa, 0x8a, 0xb6, 0xb6, 0x76, 0x29, 0x64, 0xf2, 0x3e, 0xdc, 0x5a, 0x96,
+ 0xd0, 0x3f, 0x76, 0x25, 0x0e, 0xf6, 0xb5, 0xcf, 0x86, 0x9e, 0x9e, 0xc3, 0x41, 0x39, 0xd3, 0x6f,
+ 0xb2, 0x28, 0x72, 0xf9, 0xa5, 0x2a, 0xa7, 0xc1, 0x34, 0xcf, 0x42, 0xdd, 0xa7, 0x5d, 0x56, 0xd2,
+ 0x28, 0x02, 0xe6, 0x6e, 0x10, 0xa2, 0x2a, 0xb5, 0xb2, 0x19, 0x49, 0xa5, 0x96, 0xc5, 0x17, 0x71,
+ 0xf2, 0x93, 0x2a, 0xb3, 0x32, 0x58, 0x91, 0xfe, 0xe9, 0x00, 0x29, 0x9f, 0xf4, 0x18, 0xa5, 0x1b,
+ 0x84, 0x84, 0x42, 0xdf, 0xa6, 0xf6, 0x6c, 0x35, 0xb5, 0x2a, 0x3a, 0xf2, 0x08, 0x86, 0x56, 0x3e,
+ 0x4e, 0xd3, 0xd0, 0x04, 0xb0, 0x04, 0xe5, 0xbd, 0x76, 0x85, 0x47, 0x99, 0xef, 0xbd, 0x2a, 0xdf,
+ 0x75, 0x4c, 0x35, 0xb7, 0x30, 0xf5, 0x7d, 0x95, 0xa9, 0x1c, 0xbf, 0x20, 0xa7, 0x70, 0x50, 0x76,
+ 0x65, 0x28, 0xb2, 0xb0, 0xf8, 0xb4, 0x0f, 0x26, 0x9b, 0x5b, 0x58, 0x9d, 0x3f, 0xfd, 0x6d, 0x8d,
+ 0x9e, 0x5c, 0x5f, 0x86, 0xee, 0x54, 0xa1, 0x3f, 0x5a, 0xb5, 0x8a, 0x29, 0x9a, 0xf9, 0xc4, 0x6f,
+ 0x4f, 0x6a, 0x0a, 0xca, 0xd6, 0x9d, 0xc9, 0x87, 0xd0, 0x7d, 0x89, 0xd1, 0x0c, 0x7d, 0x1f, 0xf3,
+ 0x36, 0x5d, 0xdf, 0x69, 0x12, 0x64, 0x9d, 0x53, 0xe3, 0x45, 0xff, 0x72, 0x60, 0x68, 0x66, 0x74,
+ 0x15, 0xea, 0x7f, 0x33, 0x22, 0xb6, 0xdd, 0x86, 0xdb, 0x3f, 0x97, 0xab, 0x1b, 0xa3, 0x75, 0x5d,
+ 0x63, 0xd0, 0x9f, 0xe1, 0x4e, 0x6d, 0x3e, 0xbb, 0x4d, 0x90, 0x87, 0xd0, 0xf7, 0x92, 0x78, 0x1e,
+ 0xf0, 0x48, 0x6f, 0x37, 0x65, 0xa8, 0x2d, 0x7d, 0xc5, 0x91, 0x9e, 0xc3, 0x1d, 0x86, 0x92, 0x07,
+ 0xb8, 0xc4, 0x2d, 0x7c, 0x96, 0xf8, 0x72, 0x36, 0xf8, 0x1a, 0xc3, 0x4d, 0xaf, 0x3a, 0xff, 0x0c,
+ 0xa9, 0xeb, 0x6a, 0xca, 0xe1, 0x6e, 0xfd, 0x41, 0xbb, 0x25, 0xfa, 0x01, 0xb4, 0xb9, 0x6e, 0xcb,
+ 0xda, 0x14, 0xf3, 0x8e, 0x65, 0xc6, 0x85, 0x3e, 0x85, 0xd7, 0x37, 0xc6, 0xb8, 0x7a, 0x70, 0x2e,
+ 0x12, 0x21, 0x8f, 0x7d, 0x9f, 0xdb, 0x96, 0xee, 0xb2, 0xb2, 0x4a, 0x35, 0x81, 0xf0, 0x16, 0x58,
+ 0x5c, 0x9d, 0x46, 0xa2, 0x29, 0x90, 0x3c, 0xd4, 0xf1, 0xf4, 0x4c, 0x5d, 0x93, 0xa7, 0xb1, 0xe4,
+ 0x97, 0xaf, 0x7a, 0xf5, 0xaa, 0xd7, 0xa6, 0x0c, 0x64, 0x68, 0x9f, 0xb8, 0xb9, 0xa0, 0x5e, 0x45,
+ 0x12, 0xa3, 0x34, 0x74, 0x25, 0xfa, 0xa6, 0xb5, 0x56, 0x0a, 0xfa, 0x8f, 0x63, 0x8f, 0xfc, 0x2a,
+ 0x89, 0x70, 0x57, 0xae, 0x3e, 0x29, 0x5d, 0xbc, 0x6a, 0x12, 0xdc, 0x9b, 0x6c, 0xc6, 0xca, 0xef,
+ 0x62, 0x9d, 0x89, 0xb9, 0x90, 0x15, 0xc5, 0x5e, 0xc6, 0x03, 0x14, 0x7a, 0x7c, 0x2a, 0x8a, 0x37,
+ 0xb3, 0x66, 0xc6, 0x65, 0xf8, 0x14, 0x60, 0x15, 0x41, 0x3d, 0x5b, 0x2f, 0xf0, 0xd2, 0x50, 0xa1,
+ 0x96, 0xe4, 0x3d, 0x68, 0x2d, 0xdd, 0x30, 0xc3, 0xa2, 0x5c, 0x35, 0xb1, 0x72, 0x8f, 0xcf, 0x1b,
+ 0x9f, 0x39, 0x27, 0x9d, 0xef, 0xda, 0xf9, 0x9f, 0x8e, 0x59, 0x5b, 0xff, 0xa7, 0xf8, 0xe8, 0xdf,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xdb, 0x8f, 0x7b, 0x26, 0x93, 0x0c, 0x00, 0x00,
+}
diff --git a/server/broker/broker.proto b/server/broker/broker.proto
new file mode 100644
index 0000000..645e064
--- /dev/null
+++ b/server/broker/broker.proto
@@ -0,0 +1,158 @@
+syntax = "proto3";
+
+import "server/core/proto/services.proto";
+option go_package = "broker";
+
+/*
+Definitions of objects
+*/
+
+message Participant {
+ int32 id = 1;
+ string appId = 2;
+ string serviceName = 3;
+}
+
+message Version {
+ int32 id = 1;
+ string number = 2;
+ int32 participantId = 3;
+ int32 order = 4;
+}
+
+message Pact {
+ int32 id = 1;
+ int32 consumerParticipantId = 2;
+ int32 providerParticipantId = 3;
+ bytes sha = 4;
+ bytes content = 5;
+}
+
+message PactVersion {
+ int32 id = 1;
+ int32 versionId = 2;
+ int32 pactId = 3;
+ int32 providerParticipantId = 4;
+}
+
+message Tag {
+ string name = 1;
+ int32 versionId = 2;
+}
+
+message PublishPactRequest {
+ string providerId = 1;
+ string consumerId = 2;
+ string version = 3;
+ bytes pact = 4;
+}
+
+message PublishPactResponse {
+ Response response = 1;
+}
+
+message GetAllProviderPactsRequest {
+ string providerId = 1;
+ BaseBrokerRequest baseUrl = 2;
+}
+
+message ConsumerInfo {
+ string href = 1;
+ string name = 2;
+}
+
+message Links {
+ repeated ConsumerInfo pacts = 1;
+}
+
+message GetAllProviderPactsResponse {
+ Response response = 1;
+ Links _links = 2;
+}
+
+message GetProviderConsumerVersionPactRequest {
+ string providerId = 1;
+ string consumerId = 2;
+ string version = 3;
+ BaseBrokerRequest baseUrl = 4;
+}
+
+message GetProviderConsumerVersionPactResponse {
+ Response response = 1;
+ bytes pact = 2;
+}
+
+message Verification {
+ int32 id = 1;
+ int32 number = 2;
+ int32 pactVersionId = 3; // id of the version object
+ bool success = 4;
+ string providerVersion = 5;
+ string buildUrl = 6;
+ string verificationDate = 7;
+}
+
+message VerificationSummary {
+ repeated string successful = 1;
+ repeated string failed = 2;
+ repeated string unknown = 3;
+}
+
+message VerificationDetail {
+ string providerName = 1;
+ string providerApplicationVersion = 2;
+ bool success = 3;
+ string verificationDate = 4;
+}
+
+message VerificationDetails {
+ repeated VerificationDetail verificationResults = 1;
+}
+
+message VerificationResult {
+ bool success = 1;
+ VerificationSummary providerSummary = 2;
+ VerificationDetails _embedded = 3;
+}
+
+message PublishVerificationRequest {
+ string providerId = 1;
+ string consumerId = 2;
+ int32 pactId = 3;
+ bool success = 4;
+ string providerApplicationVersion = 5;
+}
+
+message PublishVerificationResponse {
+ Response response = 1;
+ VerificationDetail confirmation = 2;
+}
+
+message RetrieveVerificationRequest {
+ string consumerId = 1;
+ string consumerVersion = 2;
+}
+
+message RetrieveVerificationResponse {
+ Response response = 1;
+ VerificationResult result = 2;
+}
+
+message BaseBrokerRequest {
+ string hostAddress = 1;
+ string scheme = 2;
+}
+
+
+message BrokerAPIInfoEntry {
+ string href = 1;
+ string name = 2;
+ string title = 3;
+ bool templated = 4;
+}
+
+message BrokerHomeResponse {
+ Response response = 1;
+ map<string, BrokerAPIInfoEntry> _links = 2;
+ repeated BrokerAPIInfoEntry curies = 3;
+}
diff --git a/server/broker/broker_key_generator.go b/server/broker/broker_key_generator.go
new file mode 100644
index 0000000..e10ebdb
--- /dev/null
+++ b/server/broker/broker_key_generator.go
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "strconv"
+
+ "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+)
+
+const (
+ BROKER_ROOT_KEY = "cse-pact"
+ BROKER_PARTICIPANT_KEY = "participant"
+ BROKER_VERSION_KEY = "version"
+ BROKER_PACT_KEY = "pact"
+ BROKER_PACT_VERSION_KEY = "pact-version"
+ BROKER_PACT_TAG_KEY = "pact-tag"
+ BROKER_PACT_VERIFICATION_KEY = "verification"
+ BROKER_PACT_LATEST = "latest"
+)
+
+// GetBrokerRootKey returns url (/cse-pact)
+func GetBrokerRootKey() string {
+ return util.StringJoin([]string{
+ "",
+ BROKER_ROOT_KEY,
+ }, "/")
+}
+
+//GetBrokerLatestKey returns pact related keys
+func GetBrokerLatestKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PACT_LATEST,
+ tenant,
+ }, "/")
+}
+
+//GetBrokerParticipantKey returns the participant root key
+func GetBrokerParticipantKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PARTICIPANT_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerParticipantKey returns the participant key
+func GenerateBrokerParticipantKey(tenant string, appId string, serviceName string) string {
+ return util.StringJoin([]string{
+ GetBrokerParticipantKey(tenant),
+ appId,
+ serviceName,
+ }, "/")
+}
+
+//GetBrokerVersionKey returns th root version key
+func GetBrokerVersionKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_VERSION_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerVersionKey returns the version key
+func GenerateBrokerVersionKey(tenant string, number string, participantId int32) string {
+ return util.StringJoin([]string{
+ GetBrokerVersionKey(tenant),
+ number,
+ strconv.Itoa(int(participantId)),
+ }, "/")
+}
+
+//GetBrokerPactKey returns the pact root key
+func GetBrokerPactKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PACT_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerPactKey returns the pact key
+func GenerateBrokerPactKey(tenant string, consumerParticipantId int32,
+ providerParticipantId int32, sha []byte) string {
+ return util.StringJoin([]string{
+ GetBrokerPactKey(tenant),
+ strconv.Itoa(int(consumerParticipantId)),
+ strconv.Itoa(int(providerParticipantId)),
+ string(sha),
+ }, "/")
+}
+
+//GetBrokerPactVersionKey returns the pact version root key
+func GetBrokerPactVersionKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PACT_VERSION_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerPactVersionKey returns the pact version root key
+func GenerateBrokerPactVersionKey(tenant string, versionId int32, pactId int32) string {
+ return util.StringJoin([]string{
+ GetBrokerPactVersionKey(tenant),
+ strconv.Itoa(int(versionId)),
+ strconv.Itoa(int(pactId)),
+ }, "/")
+}
+
+//GetBrokerTagKey returns the broker tag root key
+func GetBrokerTagKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PACT_TAG_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerTagKey returns the broker tag key
+func GenerateBrokerTagKey(tenant string, versionId int32) string {
+ return util.StringJoin([]string{
+ GetBrokerTagKey(tenant),
+ strconv.Itoa(int(versionId)),
+ }, "/")
+}
+
+//GetBrokerVerificationKey returns the verification root key
+func GetBrokerVerificationKey(tenant string) string {
+ return util.StringJoin([]string{
+ GetBrokerRootKey(),
+ BROKER_PACT_VERIFICATION_KEY,
+ tenant,
+ }, "/")
+}
+
+//GenerateBrokerVerificationKey returns he verification key
+func GenerateBrokerVerificationKey(tenant string, pactVersionId int32, number int32) string {
+ return util.StringJoin([]string{
+ GetBrokerVerificationKey(tenant),
+ strconv.Itoa(int(pactVersionId)),
+ strconv.Itoa(int(number)),
+ }, "/")
+}
+
+//GetBrokerLatestParticipantIDKey returns the latest participant ID
+func GetBrokerLatestParticipantIDKey() string {
+ return util.StringJoin([]string{
+ GetBrokerLatestKey("default"),
+ BROKER_PARTICIPANT_KEY,
+ }, "/")
+}
+
+//GetBrokerLatestVersionIDKey returns latest version ID
+func GetBrokerLatestVersionIDKey() string {
+ return util.StringJoin([]string{
+ GetBrokerLatestKey("default"),
+ BROKER_VERSION_KEY,
+ }, "/")
+}
+
+//GetBrokerLatestPactIDKey returns latest pact ID
+func GetBrokerLatestPactIDKey() string {
+ return util.StringJoin([]string{
+ GetBrokerLatestKey("default"),
+ BROKER_PACT_KEY,
+ }, "/")
+}
+
+//GetBrokerLatestPactVersionIDKey returns lated pact version ID
+func GetBrokerLatestPactVersionIDKey() string {
+ return util.StringJoin([]string{
+ GetBrokerLatestKey("default"),
+ BROKER_PACT_VERSION_KEY,
+ }, "/")
+}
+
+//GetBrokerLatestVerificationIDKey returns the lastest verification ID
+func GetBrokerLatestVerificationIDKey() string {
+ return util.StringJoin([]string{
+ GetBrokerLatestKey("default"),
+ BROKER_PACT_VERIFICATION_KEY,
+ }, "/")
+}
diff --git a/server/broker/controller.go b/server/broker/controller.go
new file mode 100644
index 0000000..2f817c5
--- /dev/null
+++ b/server/broker/controller.go
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+
+ "github.com/apache/incubator-servicecomb-service-center/pkg/rest"
+ scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
+ "github.com/apache/incubator-servicecomb-service-center/server/rest/controller"
+)
+
+const DEFAULT_SCHEME = "http"
+
+type BrokerController struct {
+}
+
+func (brokerService *BrokerController) URLPatterns() []rest.Route {
+ return []rest.Route{
+ // for handling broker requests
+ {rest.HTTP_METHOD_GET,
+ "/",
+ brokerService.GetHome},
+ {rest.HTTP_METHOD_PUT,
+ "/pacts/provider/:providerId/consumer/:consumerId/version/:number",
+ brokerService.PublishPact},
+ {rest.HTTP_METHOD_GET,
+ "/pacts/provider/:providerId/latest",
+ brokerService.GetAllProviderPacts},
+ {rest.HTTP_METHOD_GET,
+ "/pacts/provider/:providerId/consumer/:consumerId/version/:number",
+ brokerService.GetPactsOfProvider},
+ {rest.HTTP_METHOD_DELETE,
+ "/pacts/delete",
+ brokerService.DeletePacts},
+ {rest.HTTP_METHOD_POST,
+ "/pacts/provider/:providerId/consumer/:consumerId/pact-version/:sha/verification-results",
+ brokerService.PublishVerificationResults},
+ {rest.HTTP_METHOD_GET,
+ "/verification-results/consumer/:consumerId/version/:consumerVersion/latest",
+ brokerService.RetrieveVerificationResults},
+ }
+}
+
+func (brokerService *BrokerController) GetHome(w http.ResponseWriter, r *http.Request) {
+ request := &BaseBrokerRequest{
+ HostAddress: r.Host,
+ Scheme: getScheme(r),
+ }
+ resp, _ := BrokerServiceAPI.GetBrokerHome(r.Context(), request)
+
+ respInternal := resp.Response
+ resp.Response = nil
+ controller.WriteResponse(w, respInternal, resp)
+}
+
+func (*BrokerController) PublishPact(w http.ResponseWriter, r *http.Request) {
+ message, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ PactLogger.Error("body err\n", err)
+ controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
+ return
+ }
+ request := &PublishPactRequest{
+ ProviderId: r.URL.Query().Get(":providerId"),
+ ConsumerId: r.URL.Query().Get(":consumerId"),
+ Version: r.URL.Query().Get(":number"),
+ Pact: message,
+ }
+ PactLogger.Infof("PublishPact: providerId = %s, consumerId = %s, version = %s\n",
+ request.ProviderId, request.ConsumerId, request.Version)
+ resp, err := BrokerServiceAPI.PublishPact(r.Context(), request)
+
+ respInternal := resp.Response
+ resp.Response = nil
+ controller.WriteResponse(w, respInternal, resp)
+}
+
+func (*BrokerController) GetAllProviderPacts(w http.ResponseWriter, r *http.Request) {
+ request := &GetAllProviderPactsRequest{
+ ProviderId: r.URL.Query().Get(":providerId"),
+ BaseUrl: &BaseBrokerRequest{
+ HostAddress: r.Host,
+ Scheme: getScheme(r),
+ },
+ }
+ resp, err := BrokerServiceAPI.GetAllProviderPacts(r.Context(), request /*, href*/)
+ linksObj, err := json.Marshal(resp)
+ if err != nil {
+ return
+ }
+ PactLogger.Infof("Pact info: %s\n", string(linksObj))
+ respInternal := resp.Response
+ resp.Response = nil
+ controller.WriteResponse(w, respInternal, resp)
+}
+
+func (*BrokerController) GetPactsOfProvider(w http.ResponseWriter, r *http.Request) {
+ request := &GetProviderConsumerVersionPactRequest{
+ ProviderId: r.URL.Query().Get(":providerId"),
+ ConsumerId: r.URL.Query().Get(":consumerId"),
+ Version: r.URL.Query().Get(":number"),
+ BaseUrl: &BaseBrokerRequest{
+ HostAddress: r.Host,
+ Scheme: getScheme(r),
+ },
+ }
+
+ resp, _ := BrokerServiceAPI.GetPactsOfProvider(r.Context(), request)
+ respInternal := resp.Response
+ resp.Response = nil
+ //controller.WriteResponse(w, respInternal, resp.Pact)
+ controller.WriteBytes(w, respInternal, resp.Pact)
+}
+
+func (*BrokerController) DeletePacts(w http.ResponseWriter, r *http.Request) {
+ resp, _ := BrokerServiceAPI.DeletePacts(r.Context(), &BaseBrokerRequest{
+ HostAddress: r.Host,
+ Scheme: getScheme(r),
+ })
+ controller.WriteResponse(w, resp, nil)
+}
+
+func (*BrokerController) PublishVerificationResults(w http.ResponseWriter, r *http.Request) {
+ requestBody, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ PactLogger.Error("body err", err)
+ controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
+ return
+ }
+ request := &PublishVerificationRequest{}
+ err = json.Unmarshal(requestBody, request)
+ if err != nil {
+ PactLogger.Error("Unmarshal error", err)
+ controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
+ return
+ }
+ request.ProviderId = r.URL.Query().Get(":providerId")
+ request.ConsumerId = r.URL.Query().Get(":consumerId")
+ i, err := strconv.ParseInt(r.URL.Query().Get(":sha"), 10, 32)
+ if err != nil {
+ PactLogger.Error("Invalid pactId", err)
+ controller.WriteError(w, scerr.ErrInvalidParams, err.Error())
+ return
+ }
+ request.PactId = int32(i)
+ PactLogger.Infof("PublishVerificationResults: %s, %s, %d, %t, %s\n",
+ request.ProviderId, request.ConsumerId, request.PactId, request.Success,
+ request.ProviderApplicationVersion)
+ resp, err := BrokerServiceAPI.PublishVerificationResults(r.Context(),
+ request)
+ respInternal := resp.Response
+ resp.Response = nil
+ controller.WriteResponse(w, respInternal, resp)
+}
+
+func (*BrokerController) RetrieveVerificationResults(w http.ResponseWriter, r *http.Request) {
+ request := &RetrieveVerificationRequest{}
+ request.ConsumerId = r.URL.Query().Get(":consumerId")
+ request.ConsumerVersion = r.URL.Query().Get(":consumerVersion")
+ PactLogger.Infof("Retrieve verification results for: %s, %s\n",
+ request.ConsumerId, request.ConsumerVersion)
+ resp, _ := BrokerServiceAPI.RetrieveVerificationResults(r.Context(), request)
+ respInternal := resp.Response
+ resp.Response = nil
+ controller.WriteResponse(w, respInternal, resp)
+}
+
+func getScheme(r *http.Request) string {
+ if len(r.URL.Scheme) < 1 {
+ return DEFAULT_SCHEME
+ }
+ return r.URL.Scheme
+}
diff --git a/server/broker/service.go b/server/broker/service.go
new file mode 100644
index 0000000..bde8f3e
--- /dev/null
+++ b/server/broker/service.go
@@ -0,0 +1,874 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "crypto/sha1"
+ "encoding/json"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+ apt "github.com/apache/incubator-servicecomb-service-center/server/core"
+ pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+ scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
+ "github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
+ serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
+ "golang.org/x/net/context"
+)
+
+var BrokerServiceAPI *BrokerService = &BrokerService{}
+
+type BrokerService struct {
+}
+
+func (*BrokerService) GetBrokerHome(ctx context.Context,
+ in *BaseBrokerRequest) (*BrokerHomeResponse, error) {
+
+ if in == nil || len(in.HostAddress) == 0 {
+ PactLogger.Errorf(nil, "Get Participant versions request failed: invalid params.")
+ return &BrokerHomeResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+
+ return GetBrokerHomeResponse(in.HostAddress, in.Scheme), nil
+}
+
+func (*BrokerService) GetPactsOfProvider(ctx context.Context,
+ in *GetProviderConsumerVersionPactRequest) (*GetProviderConsumerVersionPactResponse, error) {
+ PactLogger.Infof("GetPactsOfProvider: (%s, %s, %s)\n",
+ in.ProviderId, in.ConsumerId, in.Version)
+
+ resp, pactId, err := RetrieveProviderConsumerPact(ctx, in)
+ if err != nil || resp.GetPact() == nil || pactId == -1 {
+ PactLogger.Errorf(nil, "Get pacts of provider failed: %s\n",
+ resp.Response.Message)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, err.Error()),
+ }, err
+ }
+
+ urlValue := GenerateBrokerAPIPath(in.BaseUrl.Scheme, in.BaseUrl.HostAddress,
+ BROKER_PUBLISH_VERIFICATION_URL,
+ strings.NewReplacer(":providerId", in.ProviderId,
+ ":consumerId", in.ConsumerId,
+ ":pact", fmt.Sprint(pactId)))
+
+ links := ",\"_links\": {" +
+ "\"pb:publish-verification-results\": {" +
+ "\"title\": \"Publish verification results\"," +
+ "\"href\": \"" + urlValue +
+ "\"" +
+ "}" +
+ "}}"
+
+ linksBytes := []byte(links)
+ pactBytes := resp.GetPact()
+ sliceOfResp := pactBytes[0 : len(pactBytes)-2]
+ finalBytes := append(sliceOfResp, linksBytes...)
+
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "Success."),
+ Pact: finalBytes,
+ }, nil
+ //controller.WriteText(http.StatusBadRequest, resp.Response.Message, w)
+
+}
+
+func (*BrokerService) DeletePacts(ctx context.Context,
+ in *BaseBrokerRequest) (*pb.Response, error) {
+
+ resp, err := DeletePactData(ctx, in)
+
+ return resp, err
+}
+
+func (*BrokerService) RetrieveProviderPacts(ctx context.Context,
+ in *GetAllProviderPactsRequest) (*GetAllProviderPactsResponse, error) {
+ if in == nil || len(in.ProviderId) == 0 {
+ PactLogger.Errorf(nil, "all provider pact retrieve request failed: invalid params.")
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+ tenant := GetDefaultTenantProject()
+
+ provider, err := serviceUtil.GetService(ctx, tenant, in.ProviderId)
+ if err != nil {
+ PactLogger.Errorf(err, "all provider pact retrieve failed, providerId is %s: query provider failed.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query provider failed."),
+ }, err
+ }
+ if provider == nil {
+ PactLogger.Errorf(nil, "all provider pact retrieve failed, providerId is %s: provider not exist.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider does not exist."),
+ }, nil
+ }
+ // Get the provider participant
+ //providerParticipantKey := apt.GenerateBrokerParticipantKey(tenant, provider.AppId, provider.ServiceName)
+ providerParticipant, err := GetParticipant(ctx, tenant, provider.AppId, provider.ServiceName)
+ if err != nil || providerParticipant == nil {
+ PactLogger.Errorf(nil, "all provider pact retrieve failed, provider participant cannot be searched.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider participant cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Provider participant id : %d", providerParticipant.Id)
+ // Get all versions
+ versionKey := util.StringJoin([]string{GetBrokerVersionKey(tenant), ""}, "/")
+ versions, err := Store().Version().Search(ctx,
+ registry.WithPrefix(),
+ registry.WithStrKey(versionKey))
+
+ if err != nil {
+ return nil, err
+ }
+ if len(versions.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPacts] No versions found, sorry")
+ return nil, nil
+ }
+ // Store versions in a map
+ versionObjects := make(map[int32]Version)
+ for i := 0; i < len(versions.Kvs); i++ {
+ version := &Version{}
+ err = json.Unmarshal(versions.Kvs[i].Value, version)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Version found : (%d, %s)", version.Id, version.Number)
+ versionObjects[version.Id] = *version
+ }
+ // Get all pactversions and filter using the provider participant id
+ pactVersionKey := util.StringJoin([]string{GetBrokerPactVersionKey(tenant), ""}, "/")
+ pactVersions, err := Store().PactVersion().Search(ctx,
+ registry.WithStrKey(pactVersionKey),
+ registry.WithPrefix())
+
+ if err != nil {
+ return nil, err
+ }
+ if len(pactVersions.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPacts] No pact version found, sorry")
+ return nil, nil
+ }
+ participantToVersionObj := make(map[int32]Version)
+ for i := 0; i < len(pactVersions.Kvs); i++ {
+ pactVersion := &PactVersion{}
+ err = json.Unmarshal(pactVersions.Kvs[i].Value, pactVersion)
+ if err != nil {
+ return nil, err
+ }
+ if pactVersion.ProviderParticipantId != providerParticipant.Id {
+ continue
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Pact version found: (%d, %d, %d, %d)", pactVersion.Id, pactVersion.VersionId, pactVersion.PactId, pactVersion.ProviderParticipantId)
+ vObj := versionObjects[pactVersion.VersionId]
+ if v1Obj, ok := participantToVersionObj[vObj.ParticipantId]; ok {
+ if vObj.Order > v1Obj.Order {
+ participantToVersionObj[vObj.ParticipantId] = vObj
+ }
+ } else {
+ participantToVersionObj[vObj.ParticipantId] = vObj
+ }
+ }
+ // Get all participants
+ participantKey := util.StringJoin([]string{GetBrokerParticipantKey(tenant), ""}, "/")
+ participants, err := Store().Participant().Search(ctx,
+ registry.WithStrKey(participantKey),
+ registry.WithPrefix())
+
+ if err != nil {
+ return nil, err
+ }
+ if len(participants.Kvs) == 0 {
+ return nil, nil
+ }
+ consumerInfoArr := make([]*ConsumerInfo, 0)
+ for i := 0; i < len(participants.Kvs); i++ {
+ participant := &Participant{}
+ err = json.Unmarshal(participants.Kvs[i].Value, participant)
+ if err != nil {
+ return nil, err
+ }
+ if _, ok := participantToVersionObj[participant.Id]; !ok {
+ continue
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Consumer found: (%d, %s, %s)", participant.Id, participant.AppId, participant.ServiceName)
+ consumerVersion := participantToVersionObj[participant.Id].Number
+ consumerId, err := serviceUtil.GetServiceId(ctx, &pb.MicroServiceKey{
+ Tenant: tenant,
+ AppId: participant.AppId,
+ ServiceName: participant.ServiceName,
+ Version: consumerVersion,
+ })
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Consumer microservice found: %s", consumerId)
+
+ urlValue := GenerateBrokerAPIPath(in.BaseUrl.Scheme, in.BaseUrl.HostAddress,
+ BROKER_PUBLISH_URL,
+ strings.NewReplacer(":providerId", in.ProviderId,
+ ":consumerId", consumerId,
+ ":number", consumerVersion))
+
+ consumerInfo := &ConsumerInfo{
+ Href: urlValue,
+ Name: consumerId,
+ }
+ consumerInfoArr = append(consumerInfoArr, consumerInfo)
+ }
+ links := &Links{
+ Pacts: consumerInfoArr,
+ }
+ resJson, err := json.Marshal(links)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("Json : %s", string(resJson))
+ response := &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "retrieve provider pact info succeeded."),
+ XLinks: links,
+ }
+ return response, nil
+}
+
+func (*BrokerService) GetAllProviderPacts(ctx context.Context,
+ in *GetAllProviderPactsRequest) (*GetAllProviderPactsResponse, error) {
+
+ if in == nil || len(in.ProviderId) == 0 {
+ PactLogger.Errorf(nil, "all provider pact retrieve request failed: invalid params.")
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+ tenant := GetDefaultTenantProject()
+
+ provider, err := serviceUtil.GetService(ctx, tenant, in.ProviderId)
+ if err != nil {
+ PactLogger.Errorf(err, "all provider pact retrieve failed, providerId is %s: query provider failed.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query provider failed."),
+ }, err
+ }
+ if provider == nil {
+ PactLogger.Errorf(nil, "all provider pact retrieve failed, providerId is %s: provider not exist.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider does not exist."),
+ }, nil
+ }
+ // Get the provider participant
+ //providerParticipantKey := apt.GenerateBrokerParticipantKey(tenant, provider.AppId, provider.ServiceName)
+ providerParticipant, err := GetParticipant(ctx, tenant, provider.AppId, provider.ServiceName)
+ if err != nil || providerParticipant == nil {
+ PactLogger.Errorf(nil, "all provider pact retrieve failed, provider participant cannot be searched.", in.ProviderId)
+ return &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider participant cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Provider participant id : %d", providerParticipant.Id)
+ // Get all versions
+ versionKey := util.StringJoin([]string{GetBrokerVersionKey(tenant), ""}, "/")
+ versions, err := Store().Version().Search(ctx,
+ registry.WithPrefix(),
+ registry.WithStrKey(versionKey))
+
+ if err != nil {
+ return nil, err
+ }
+ if len(versions.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPacts] No versions found, sorry")
+ return nil, nil
+ }
+ // Store versions in a map
+ versionObjects := make(map[int32]Version)
+ for i := 0; i < len(versions.Kvs); i++ {
+ version := &Version{}
+ err = json.Unmarshal(versions.Kvs[i].Value, version)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Version found : (%d, %s)", version.Id, version.Number)
+ versionObjects[version.Id] = *version
+ }
+ // Get all pactversions and filter using the provider participant id
+ pactVersionKey := util.StringJoin([]string{GetBrokerPactVersionKey(tenant), ""}, "/")
+ pactVersions, err := Store().PactVersion().Search(ctx,
+ registry.WithStrKey(pactVersionKey),
+ registry.WithPrefix())
+
+ if err != nil {
+ return nil, err
+ }
+ if len(pactVersions.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPacts] No pact version found, sorry")
+ return nil, nil
+ }
+ participantToVersionObj := make(map[int32]Version)
+ for i := 0; i < len(pactVersions.Kvs); i++ {
+ pactVersion := &PactVersion{}
+ err = json.Unmarshal(pactVersions.Kvs[i].Value, pactVersion)
+ if err != nil {
+ return nil, err
+ }
+ if pactVersion.ProviderParticipantId != providerParticipant.Id {
+ continue
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Pact version found: (%d, %d, %d, %d)", pactVersion.Id, pactVersion.VersionId, pactVersion.PactId, pactVersion.ProviderParticipantId)
+ vObj := versionObjects[pactVersion.VersionId]
+ if v1Obj, ok := participantToVersionObj[vObj.ParticipantId]; ok {
+ if vObj.Order > v1Obj.Order {
+ participantToVersionObj[vObj.ParticipantId] = vObj
+ }
+ } else {
+ participantToVersionObj[vObj.ParticipantId] = vObj
+ }
+ }
+ // Get all participants
+ participantKey := util.StringJoin([]string{GetBrokerParticipantKey(tenant), ""}, "/")
+ participants, err := Store().Participant().Search(ctx,
+ registry.WithStrKey(participantKey),
+ registry.WithPrefix())
+
+ if err != nil {
+ return nil, err
+ }
+ if len(participants.Kvs) == 0 {
+ return nil, nil
+ }
+ consumerInfoArr := make([]*ConsumerInfo, 0)
+ for i := 0; i < len(participants.Kvs); i++ {
+ participant := &Participant{}
+ err = json.Unmarshal(participants.Kvs[i].Value, participant)
+ if err != nil {
+ return nil, err
+ }
+ if _, ok := participantToVersionObj[participant.Id]; !ok {
+ continue
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Consumer found: (%d, %s, %s)", participant.Id, participant.AppId, participant.ServiceName)
+ consumerVersion := participantToVersionObj[participant.Id].Number
+ consumerId, err := serviceUtil.GetServiceId(ctx, &pb.MicroServiceKey{
+ Tenant: tenant,
+ AppId: participant.AppId,
+ ServiceName: participant.ServiceName,
+ Version: consumerVersion,
+ })
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("[RetrieveProviderPacts] Consumer microservice found: %s", consumerId)
+
+ urlValue := GenerateBrokerAPIPath(in.BaseUrl.Scheme, in.BaseUrl.HostAddress,
+ BROKER_PUBLISH_URL,
+ strings.NewReplacer(":providerId", in.ProviderId,
+ ":consumerId", consumerId,
+ ":number", consumerVersion))
+
+ consumerInfo := &ConsumerInfo{
+ Href: urlValue,
+ Name: consumerId,
+ }
+ consumerInfoArr = append(consumerInfoArr, consumerInfo)
+ }
+ links := &Links{
+ Pacts: consumerInfoArr,
+ }
+ resJson, err := json.Marshal(links)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("Json : %s", string(resJson))
+ response := &GetAllProviderPactsResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "retrieve provider pact info succeeded."),
+ XLinks: links,
+ }
+ return response, nil
+}
+
+func (*BrokerService) RetrieveVerificationResults(ctx context.Context, in *RetrieveVerificationRequest) (*RetrieveVerificationResponse, error) {
+ if in == nil || len(in.ConsumerId) == 0 || len(in.ConsumerVersion) == 0 {
+ PactLogger.Errorf(nil, "verification result retrieve request failed: invalid params.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+ tenant := GetDefaultTenantProject()
+ consumer, err := serviceUtil.GetService(ctx, tenant, in.ConsumerId)
+ if err != nil {
+ PactLogger.Errorf(err, "verification result retrieve request failed, consumerId is %s: query consumer failed.", in.ConsumerId)
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query consumer failed."),
+ }, err
+ }
+ if consumer == nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, consumerId is %s: consumer not exist.", in.ConsumerId)
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Consumer does not exist."),
+ }, nil
+ }
+ PactLogger.Infof("Consumer service found: (%s, %s, %s, %s)", consumer.ServiceId, consumer.AppId, consumer.ServiceName, consumer.Version)
+ // Get consumer participant
+ consumerParticipant, err := GetParticipant(ctx, tenant, consumer.AppId, consumer.ServiceName)
+ if err != nil || consumerParticipant == nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, consumer participant cannot be searched.", in.ConsumerId)
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "consumer participant cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("Consumer participant found: (%d, %s, %s)", consumerParticipant.Id, consumerParticipant.AppId, consumerParticipant.ServiceName)
+ // Get version
+ version, err := GetVersion(ctx, tenant, consumer.Version, consumerParticipant.Id)
+ if err != nil || version == nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, version cannot be searched.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "version cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("Version found/created: (%d, %s, %d, %d)", version.Id, version.Number, version.ParticipantId, version.Order)
+ key := util.StringJoin([]string{GetBrokerPactVersionKey(tenant), strconv.Itoa(int(version.Id))}, "/")
+ pactVersions, err := Store().PactVersion().Search(ctx,
+ registry.WithPrefix(),
+ registry.WithStrKey(key))
+
+ if err != nil || len(pactVersions.Kvs) == 0 {
+ PactLogger.Errorf(nil, "verification result publish request failed, pact version cannot be searched.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact version cannot be searched."),
+ }, err
+ }
+ overAllSuccess := false
+
+ successfuls := make([]string, 0)
+ fails := make([]string, 0)
+ unknowns := make([]string, 0)
+
+ verificationDetailsArr := make([]*VerificationDetail, 0)
+ for j := 0; j < len(pactVersions.Kvs); j++ {
+ pactVersion := &PactVersion{}
+ err = json.Unmarshal(pactVersions.Kvs[j].Value, &pactVersion)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, pact version cannot be searched.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact version cannot be searched."),
+ }, err
+ }
+ key = util.StringJoin([]string{GetBrokerVerificationKey(tenant), strconv.Itoa(int(pactVersion.Id))}, "/")
+ verifications, err := Store().Verification().Search(ctx,
+ registry.WithPrefix(),
+ registry.WithStrKey(key))
+
+ if err != nil || len(verifications.Kvs) == 0 {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, verification results cannot be searched.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification results cannot be searched."),
+ }, err
+ }
+ lastNumber := int32(math.MinInt32)
+ var lastVerificationResult *Verification
+ for i := 0; i < len(verifications.Kvs); i++ {
+ verification := &Verification{}
+ err = json.Unmarshal(verifications.Kvs[i].Value, &verification)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, verification result unmarshall error.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result unmarshall error."),
+ }, err
+ }
+ if verification.Number > lastNumber {
+ lastNumber = verification.Number
+ lastVerificationResult = verification
+ }
+ }
+ if lastVerificationResult == nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, verification result cannot be found.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result cannot be found."),
+ }, err
+ }
+ PactLogger.Infof("Verification result found: (%d, %d, %d, %t, %s, %s, %s)",
+ lastVerificationResult.Id, lastVerificationResult.Number, lastVerificationResult.PactVersionId,
+ lastVerificationResult.Success, lastVerificationResult.ProviderVersion,
+ lastVerificationResult.BuildUrl, lastVerificationResult.VerificationDate)
+
+ key = util.StringJoin([]string{GetBrokerParticipantKey(tenant), ""}, "/")
+ participants, err := Store().Participant().Search(ctx,
+ registry.WithStrKey(key),
+ registry.WithPrefix())
+
+ if err != nil || len(participants.Kvs) == 0 {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, provider participant cannot be searched.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "provider participant cannot be searched."),
+ }, err
+ }
+ var providerParticipant *Participant
+ for i := 0; i < len(participants.Kvs); i++ {
+ participant := &Participant{}
+ err = json.Unmarshal(participants.Kvs[i].Value, &participant)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, verification result unmarshall error.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result unmarshall error."),
+ }, err
+ }
+ if participant.Id == pactVersion.ProviderParticipantId {
+ providerParticipant = participant
+ break
+ }
+ }
+ if providerParticipant == nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, verification result unmarshall error.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result unmarshall error."),
+ }, err
+ }
+ serviceFindReq := &pb.GetExistenceRequest{
+ Type: "microservice",
+ AppId: providerParticipant.AppId,
+ ServiceName: providerParticipant.ServiceName,
+ Version: lastVerificationResult.ProviderVersion,
+ }
+ resp, err := apt.ServiceAPI.Exist(ctx, serviceFindReq)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result retrieve request failed, provider service cannot be found.")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "provider service cannot be found."),
+ }, err
+ }
+ providerName := resp.ServiceId
+ verificationDetail := &VerificationDetail{
+ ProviderName: providerName,
+ ProviderApplicationVersion: lastVerificationResult.ProviderVersion,
+ Success: lastVerificationResult.Success,
+ VerificationDate: lastVerificationResult.VerificationDate,
+ }
+ verificationDetailsArr = append(verificationDetailsArr, verificationDetail)
+ if verificationDetail.Success == true {
+ successfuls = append(successfuls, providerName)
+ } else {
+ fails = append(fails, providerName)
+ }
+ overAllSuccess = overAllSuccess && verificationDetail.Success
+ }
+ verificationDetails := &VerificationDetails{VerificationResults: verificationDetailsArr}
+ verificationSummary := &VerificationSummary{Successful: successfuls, Failed: fails, Unknown: unknowns}
+ verificationResult := &VerificationResult{Success: overAllSuccess, ProviderSummary: verificationSummary, XEmbedded: verificationDetails}
+ PactLogger.Infof("Verification result retrieved successfully ...")
+ return &RetrieveVerificationResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "Verification result retrieved successfully."),
+ Result: verificationResult,
+ }, nil
+}
+
+func (*BrokerService) PublishVerificationResults(ctx context.Context, in *PublishVerificationRequest) (*PublishVerificationResponse, error) {
+ if in == nil || len(in.ProviderId) == 0 || len(in.ConsumerId) == 0 {
+ PactLogger.Errorf(nil, "verification result publish request failed: invalid params.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+ tenant := GetDefaultTenantProject()
+ consumer, err := serviceUtil.GetService(ctx, tenant, in.ConsumerId)
+ if err != nil {
+ PactLogger.Errorf(err, "verification result publish request failed, consumerId is %s: query consumer failed.", in.ConsumerId)
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query consumer failed."),
+ }, err
+ }
+ if consumer == nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, consumerId is %s: consumer not exist.", in.ConsumerId)
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Consumer does not exist."),
+ }, nil
+ }
+ PactLogger.Infof("Consumer service found: (%s, %s, %s, %s)", consumer.ServiceId, consumer.AppId, consumer.ServiceName, consumer.Version)
+ // Get consumer participant
+ consumerParticipant, err := GetParticipant(ctx, tenant, consumer.AppId, consumer.ServiceName)
+ if err != nil || consumerParticipant == nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, consumer participant cannot be searched.", in.ConsumerId)
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "consumer participant cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("Consumer participant found: (%d, %s, %s)", consumerParticipant.Id, consumerParticipant.AppId, consumerParticipant.ServiceName)
+ // Get version
+ version, err := GetVersion(ctx, tenant, consumer.Version, consumerParticipant.Id)
+ if err != nil || version == nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, version cannot be searched.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "version cannot be searched."),
+ }, err
+ }
+ PactLogger.Infof("Version found/created: (%d, %s, %d, %d)", version.Id, version.Number, version.ParticipantId, version.Order)
+ key := util.StringJoin([]string{GetBrokerPactKey(tenant), ""}, "/")
+ pacts, err := Store().Pact().Search(ctx,
+ registry.WithStrKey(key),
+ registry.WithPrefix())
+
+ if err != nil || len(pacts.Kvs) == 0 {
+ PactLogger.Errorf(nil, "verification result publish request failed, pact cannot be searched.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact cannot be searched."),
+ }, err
+ }
+ pactExists := false
+ for i := 0; i < len(pacts.Kvs); i++ {
+ pact := &Pact{}
+ err = json.Unmarshal(pacts.Kvs[i].Value, &pact)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, pact cannot be searched.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact cannot be searched."),
+ }, err
+ }
+ if pact.Id == in.PactId {
+ pactExists = true
+ }
+ }
+ if pactExists == false {
+ PactLogger.Errorf(nil, "verification result publish request failed, pact does not exists.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact does not exists."),
+ }, err
+ }
+ pactVersion, err := GetPactVersion(ctx, tenant, version.Id, in.PactId)
+ if err != nil || pactVersion == nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, pact version cannot be searched.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact version cannot be searched."),
+ }, err
+ }
+ // Check if some verification results already exists
+ key = util.StringJoin([]string{GetBrokerVerificationKey(tenant), strconv.Itoa(int(pactVersion.Id))}, "/")
+ verifications, err := Store().Verification().Search(ctx,
+ registry.WithStrKey(key),
+ registry.WithPrefix())
+
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, verification result cannot be searched.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result cannot be searched."),
+ }, err
+ }
+ lastNumber := int32(math.MinInt32)
+ if len(verifications.Kvs) != 0 {
+ for i := 0; i < len(verifications.Kvs); i++ {
+ verification := &Verification{}
+ err = json.Unmarshal(verifications.Kvs[i].Value, &verification)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish request failed, verification result unmarshall error.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "verification result unmarshall error."),
+ }, err
+ }
+ if verification.Number > lastNumber {
+ lastNumber = verification.Number
+ }
+ }
+ }
+ if lastNumber < 0 {
+ lastNumber = 0
+ } else {
+ lastNumber++
+ }
+ verificationDate := time.Now().Format(time.RFC3339)
+ verificationKey := GenerateBrokerVerificationKey(tenant, pactVersion.Id, lastNumber)
+ id, err := GetData(ctx, GetBrokerLatestVerificationIDKey())
+ verification := &Verification{
+ Id: int32(id) + 1,
+ Number: lastNumber,
+ PactVersionId: pactVersion.Id,
+ Success: in.Success,
+ ProviderVersion: in.ProviderApplicationVersion,
+ BuildUrl: "",
+ VerificationDate: verificationDate,
+ }
+ response, err := CreateVerification(PactLogger, ctx, verificationKey, *verification)
+ if err != nil {
+ return response, err
+ }
+ PactLogger.Infof("Verification result inserted: (%d, %d, %d, %t, %s, %s, %s)",
+ verification.Id, verification.Number, verification.PactVersionId,
+ verification.Success, verification.ProviderVersion, verification.BuildUrl, verification.VerificationDate)
+ verificationResponse := &VerificationDetail{
+ ProviderName: in.ProviderId,
+ ProviderApplicationVersion: verification.ProviderVersion,
+ Success: verification.Success,
+ VerificationDate: verification.VerificationDate,
+ }
+ PactLogger.Infof("Verification result published successfully ...")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "Verification result published successfully."),
+ Confirmation: verificationResponse,
+ }, nil
+}
+
+func (*BrokerService) PublishPact(ctx context.Context, in *PublishPactRequest) (*PublishPactResponse, error) {
+ if in == nil || len(in.ProviderId) == 0 || len(in.ConsumerId) == 0 || len(in.Version) == 0 || len(in.Pact) == 0 {
+ PactLogger.Errorf(nil, "pact publish request failed: invalid params.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Request format invalid."),
+ }, nil
+ }
+ tenant := GetDefaultTenantProject()
+
+ provider, err := serviceUtil.GetService(ctx, tenant, in.ProviderId)
+ if err != nil {
+ PactLogger.Errorf(err, "pact publish failed, providerId is %s: query provider failed.", in.ProviderId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query provider failed."),
+ }, err
+ }
+ if provider == nil {
+ PactLogger.Errorf(nil, "pact publish failed, providerId is %s: provider not exist.", in.ProviderId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider does not exist."),
+ }, nil
+ }
+ PactLogger.Infof("Provider service found: (%s, %s, %s, %s)", provider.ServiceId, provider.AppId, provider.ServiceName, provider.Version)
+ consumer, err := serviceUtil.GetService(ctx, tenant, in.ConsumerId)
+ if err != nil {
+ PactLogger.Errorf(err, "pact publish failed, consumerId is %s: query consumer failed.", in.ConsumerId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Query consumer failed."),
+ }, err
+ }
+ if consumer == nil {
+ PactLogger.Errorf(nil, "pact publish failed, consumerId is %s: consumer not exist.", in.ConsumerId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Consumer does not exist."),
+ }, nil
+ }
+
+ // check that the consumer has that vesion in the url
+ if strings.Compare(consumer.GetVersion(), in.Version) != 0 {
+ util.Logger().Errorf(nil,
+ "pact publish failed, version (%s) does not exist for consmer", in.Version)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Consumer Version does not exist."),
+ }, nil
+ }
+
+ PactLogger.Infof("Consumer service found: (%s, %s, %s, %s)", consumer.ServiceId, consumer.AppId, consumer.ServiceName, consumer.Version)
+ // Get or create provider participant
+ providerParticipantKey := GenerateBrokerParticipantKey(tenant, provider.AppId, provider.ServiceName)
+ providerParticipant, err := GetParticipant(ctx, tenant, provider.AppId, provider.ServiceName)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, provider participant cannot be searched.", in.ProviderId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "Provider participant cannot be searched."),
+ }, err
+ }
+ if providerParticipant == nil {
+ id, err := GetData(ctx, GetBrokerLatestParticipantIDKey())
+ providerParticipant = &Participant{Id: int32(id) + 1, AppId: provider.AppId, ServiceName: provider.ServiceName}
+ response, err := CreateParticipant(PactLogger, ctx, providerParticipantKey, *providerParticipant)
+ if err != nil {
+ return response, err
+ }
+ }
+ PactLogger.Infof("Provider participant found: (%d, %s, %s)", providerParticipant.Id, providerParticipant.AppId, providerParticipant.ServiceName)
+ // Get or create consumer participant
+ consumerParticipantKey := GenerateBrokerParticipantKey(tenant, consumer.AppId, consumer.ServiceName)
+ consumerParticipant, err := GetParticipant(ctx, tenant, consumer.AppId, consumer.ServiceName)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, consumer participant cannot be searched.", in.ConsumerId)
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "consumer participant cannot be searched."),
+ }, err
+ }
+ if consumerParticipant == nil {
+ id, err := GetData(ctx, GetBrokerLatestParticipantIDKey())
+ consumerParticipant = &Participant{Id: int32(id) + 1, AppId: consumer.AppId, ServiceName: consumer.ServiceName}
+ response, err := CreateParticipant(PactLogger, ctx, consumerParticipantKey, *consumerParticipant)
+ if err != nil {
+ return response, err
+ }
+ }
+ PactLogger.Infof("Consumer participant found: (%d, %s, %s)", consumerParticipant.Id, consumerParticipant.AppId, consumerParticipant.ServiceName)
+ // Get or create version
+ versionKey := GenerateBrokerVersionKey(tenant, in.Version, consumerParticipant.Id)
+ version, err := GetVersion(ctx, tenant, in.Version, consumerParticipant.Id)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, version cannot be searched.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "version cannot be searched."),
+ }, err
+ }
+ if version == nil {
+ order := GetLastestVersionNumberForParticipant(ctx, tenant, consumerParticipant.Id)
+ PactLogger.Infof("Old version order: %d", order)
+ order++
+ id, err := GetData(ctx, GetBrokerLatestVersionIDKey())
+ version = &Version{Id: int32(id) + 1, Number: in.Version, ParticipantId: consumerParticipant.Id, Order: order}
+ response, err := CreateVersion(PactLogger, ctx, versionKey, *version)
+ if err != nil {
+ return response, err
+ }
+ }
+ PactLogger.Infof("Version found/created: (%d, %s, %d, %d)", version.Id, version.Number, version.ParticipantId, version.Order)
+ // Get or create pact
+ sha1 := sha1.Sum(in.Pact)
+ var sha []byte = sha1[:]
+ pactKey := GenerateBrokerPactKey(tenant, consumerParticipant.Id, providerParticipant.Id, sha)
+ pact, err := GetPact(ctx, tenant, consumerParticipant.Id, providerParticipant.Id, sha)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact cannot be searched.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact cannot be searched."),
+ }, err
+ }
+ if pact == nil {
+ id, err := GetData(ctx, GetBrokerLatestPactIDKey())
+ pact = &Pact{Id: int32(id) + 1, ConsumerParticipantId: consumerParticipant.Id,
+ ProviderParticipantId: providerParticipant.Id, Sha: sha, Content: in.Pact}
+ response, err := CreatePact(PactLogger, ctx, pactKey, *pact)
+ if err != nil {
+ return response, err
+ }
+ }
+ PactLogger.Infof("Pact found/created: (%d, %d, %d, %s)", pact.Id, pact.ConsumerParticipantId, pact.ProviderParticipantId, pact.Sha)
+ // Get or create pact version
+ pactVersionKey := GenerateBrokerPactVersionKey(tenant, version.Id, pact.Id)
+ pactVersion, err := GetPactVersion(ctx, tenant, version.Id, pact.Id)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact version cannot be searched.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInvalidParams, "pact version cannot be searched."),
+ }, err
+ }
+ if pactVersion == nil {
+ id, err := GetData(ctx, GetBrokerLatestPactVersionIDKey())
+ pactVersion = &PactVersion{Id: int32(id) + 1, VersionId: version.Id, PactId: pact.Id, ProviderParticipantId: providerParticipant.Id}
+ response, err := CreatePactVersion(PactLogger, ctx, pactVersionKey, *pactVersion)
+ if err != nil {
+ return response, err
+ }
+ }
+ PactLogger.Infof("PactVersion found/create: (%d, %d, %d, %d)", pactVersion.Id, pactVersion.VersionId, pactVersion.PactId, pactVersion.ProviderParticipantId)
+ PactLogger.Infof("Pact published successfully ...")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "Pact published successfully."),
+ }, nil
+}
diff --git a/server/broker/service_test.go b/server/broker/service_test.go
new file mode 100644
index 0000000..516b8c3
--- /dev/null
+++ b/server/broker/service_test.go
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "fmt"
+
+ "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+ "github.com/apache/incubator-servicecomb-service-center/server/core"
+ pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "golang.org/x/net/context"
+)
+
+const (
+ TEST_BROKER_NO_SERVICE_ID = "noServiceId"
+ TEST_BROKER_NO_VERSION = "noVersion"
+ TEST_BROKER_TOO_LONG_SERVICEID = "addasdfasaddasdfasaddasdfasaddasdfasaddasdfasaddasdfasaddasdfasadafd"
+ //Consumer
+ TEST_BROKER_CONSUMER_VERSION = "4.0.0"
+ TEST_BROKER_CONSUMER_NAME = "broker_name_consumer"
+ TEST_BROKER_CONSUMER_APP = "broker_group_consumer"
+ //Provider
+ TEST_BROKER_PROVIDER_VERSION = "3.0.0"
+ TEST_BROKER_PROVIDER_NAME = "broker_name_provider"
+ TEST_BROKER_PROVIDER_APP = "broker_group_provider"
+)
+
+var brokerResource = BrokerServiceAPI
+var serviceResource = core.ServiceAPI
+var consumerServiceId string
+var providerServiceId string
+
+var _ = Describe("BrokerController", func() {
+ Describe("brokerDependency", func() {
+ Context("normal", func() {
+ It("PublishPact", func() {
+ fmt.Println("UT===========PublishPact")
+
+ //(1) create consumer service
+ resp, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+ Service: &pb.MicroService{
+ ServiceName: TEST_BROKER_CONSUMER_NAME,
+ AppId: TEST_BROKER_CONSUMER_APP,
+ Version: TEST_BROKER_CONSUMER_VERSION,
+ Level: "FRONT",
+ Schemas: []string{
+ "xxxxxxxx",
+ },
+ Status: "UP",
+ },
+ })
+
+ Expect(err).To(BeNil())
+ consumerServiceId = resp.ServiceId
+ Expect(resp.GetResponse().Code).To(Equal(pb.Response_SUCCESS))
+
+ //(2) create provider service
+ resp, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+ Service: &pb.MicroService{
+ ServiceName: TEST_BROKER_PROVIDER_NAME,
+ AppId: TEST_BROKER_PROVIDER_APP,
+ Version: TEST_BROKER_PROVIDER_VERSION,
+ Level: "FRONT",
+ Schemas: []string{
+ "xxxxxxxx",
+ },
+ Status: "UP",
+ Properties: map[string]string{"allowCrossApp": "true"},
+ },
+ })
+ Expect(err).To(BeNil())
+ providerServiceId = resp.ServiceId
+ Expect(resp.GetResponse().Code).To(Equal(pb.Response_SUCCESS))
+
+ //(3) publish a pact between two services
+ respPublishPact, err := brokerResource.PublishPact(getContext(),
+ &PublishPactRequest{
+ ProviderId: providerServiceId,
+ ConsumerId: consumerServiceId,
+ Version: TEST_BROKER_CONSUMER_VERSION,
+ Pact: []byte("hello"),
+ })
+
+ Expect(err).To(BeNil())
+ Expect(respPublishPact.GetResponse().Code).To(Equal(pb.Response_SUCCESS))
+ })
+
+ It("PublishPact-noProviderServiceId", func() {
+ fmt.Println("UT===========PublishPact, no provider serviceID")
+
+ //publish a pact between two services
+ respPublishPact, _ := brokerResource.PublishPact(getContext(), &PublishPactRequest{
+ ProviderId: TEST_BROKER_NO_SERVICE_ID,
+ ConsumerId: consumerServiceId,
+ Version: TEST_BROKER_CONSUMER_VERSION,
+ Pact: []byte("hello"),
+ })
+
+ Expect(respPublishPact.GetResponse().Code).ToNot(Equal(pb.Response_SUCCESS))
+ })
+
+ It("PublishPact-noConumerServiceId", func() {
+ fmt.Println("UT===========PublishPact, no consumer serviceID")
+
+ //publish a pact between two services
+ respPublishPact, _ := brokerResource.PublishPact(getContext(), &PublishPactRequest{
+ ProviderId: providerServiceId,
+ ConsumerId: TEST_BROKER_NO_SERVICE_ID,
+ Version: TEST_BROKER_CONSUMER_VERSION,
+ Pact: []byte("hello"),
+ })
+
+ Expect(respPublishPact.GetResponse().Code).ToNot(Equal(pb.Response_SUCCESS))
+ })
+
+ It("PublishPact-noConumerVersion", func() {
+ fmt.Println("UT===========PublishPact, no consumer Version")
+
+ //publish a pact between two services
+ respPublishPact, _ := brokerResource.PublishPact(getContext(), &PublishPactRequest{
+ ProviderId: providerServiceId,
+ ConsumerId: consumerServiceId,
+ Version: TEST_BROKER_NO_VERSION,
+ Pact: []byte("hello"),
+ })
+
+ Expect(respPublishPact.GetResponse().Code).ToNot(Equal(pb.Response_SUCCESS))
+ })
+
+ It("GetBrokerHome", func() {
+ fmt.Println("UT===========GetBrokerHome")
+
+ respGetHome, _ := brokerResource.GetBrokerHome(getContext(), &BaseBrokerRequest{
+ HostAddress: "localhost",
+ Scheme: "http",
+ })
+
+ Expect(respGetHome).NotTo(BeNil())
+
+ })
+
+ It("GetBrokerAllProviderPacts", func() {
+ fmt.Println("UT===========GetBrokerAllProviderPacts")
+
+ respGetAllProviderPacts, _ := brokerResource.GetAllProviderPacts(getContext(),
+ &GetAllProviderPactsRequest{
+ ProviderId: providerServiceId,
+ BaseUrl: &BaseBrokerRequest{
+ HostAddress: "localhost",
+ Scheme: "http",
+ }})
+
+ Expect(respGetAllProviderPacts).NotTo(BeNil())
+ Expect(respGetAllProviderPacts.GetResponse().Code).To(Equal(pb.Response_SUCCESS))
+ })
+
+ It("GetBrokerPactsOfProvider", func() {
+ fmt.Println("UT===========GetBrokerPactsOfProvider")
+
+ respGetAllProviderPacts, _ := brokerResource.GetPactsOfProvider(getContext(),
+ &GetProviderConsumerVersionPactRequest{
+ ProviderId: providerServiceId,
+ ConsumerId: consumerServiceId,
+ Version: TEST_BROKER_CONSUMER_VERSION,
+ BaseUrl: &BaseBrokerRequest{
+ HostAddress: "localhost",
+ Scheme: "http",
+ }})
+
+ Expect(respGetAllProviderPacts).NotTo(BeNil())
+ Expect(respGetAllProviderPacts.GetResponse().Code).To(Equal(pb.Response_SUCCESS))
+ })
+
+ })
+ })
+})
+
+func getContext() context.Context {
+ ctx := context.TODO()
+ ctx = util.SetContext(ctx, "domain", "default")
+ ctx = util.SetContext(ctx, "project", "default")
+ ctx = util.SetContext(ctx, "noCache", "1")
+ return ctx
+}
diff --git a/server/broker/store.go b/server/broker/store.go
new file mode 100644
index 0000000..0cdddc5
--- /dev/null
+++ b/server/broker/store.go
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "sync"
+
+ "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+ sstore "github.com/apache/incubator-servicecomb-service-center/server/core/backend/store"
+)
+
+const (
+ PARTICIPANT sstore.StoreType = iota
+ VERSION
+ PACT
+ PACT_VERSION
+ PACT_TAG
+ VERIFICATION
+ PACT_LATEST
+ typeEnd
+)
+
+var TypeNames = []string{
+ PARTICIPANT: "PARTICIPANT",
+ VERSION: "VERSION",
+ PACT: "PACT",
+ PACT_VERSION: "PACT_VERSION",
+ PACT_TAG: "PACT_TAG",
+ VERIFICATION: "VERIFICATION",
+ PACT_LATEST: "PACT_LATEST",
+}
+
+var TypeRoots = map[sstore.StoreType]string{
+ PARTICIPANT: GetBrokerParticipantKey(""),
+ VERSION: GetBrokerVersionKey(""),
+ PACT: GetBrokerPactKey(""),
+ PACT_VERSION: GetBrokerPactVersionKey(""),
+ PACT_TAG: GetBrokerTagKey(""),
+ VERIFICATION: GetBrokerVerificationKey(""),
+ PACT_LATEST: GetBrokerLatestKey(""),
+}
+
+var store = &BKvStore{}
+
+func Store() *BKvStore {
+ return store
+}
+
+func (s *BKvStore) StoreSize(t sstore.StoreType) int {
+ return 100
+}
+
+func (s *BKvStore) newStore(t sstore.StoreType, opts ...sstore.KvCacherCfgOption) {
+ opts = append(opts,
+ sstore.WithKey(TypeRoots[t]),
+ sstore.WithInitSize(s.StoreSize(t)),
+ )
+ s.newIndexer(t, sstore.NewKvCacher(opts...))
+}
+
+func (s *BKvStore) store() {
+ for t := sstore.StoreType(0); t != typeEnd; t++ {
+ s.newStore(t)
+ }
+ for _, i := range s.bindexers {
+ <-i.Ready()
+ }
+ util.SafeCloseChan(s.bready)
+
+ util.Logger().Debugf("all indexers are ready")
+}
+
+func init() {
+ store.Initialize()
+ store.Run()
+ store.Ready()
+}
+
+type BKvStore struct {
+ *sstore.KvStore
+ bindexers map[sstore.StoreType]*sstore.Indexer
+ block sync.RWMutex
+ bready chan struct{}
+ bisClose bool
+}
+
+func (s *BKvStore) Initialize() {
+ s.KvStore = sstore.Store()
+ s.KvStore.Initialize()
+ s.bindexers = make(map[sstore.StoreType]*sstore.Indexer)
+ s.bready = make(chan struct{})
+
+ for i := sstore.StoreType(0); i != typeEnd; i++ {
+ store.newNullStore(i)
+ }
+}
+
+func (s *BKvStore) newNullStore(t sstore.StoreType) {
+ s.newIndexer(t, sstore.NullCacher)
+}
+
+func (s *BKvStore) newIndexer(t sstore.StoreType, cacher sstore.Cacher) {
+ indexer := sstore.NewCacheIndexer(t, cacher)
+ s.bindexers[t] = indexer
+ indexer.Run()
+}
+
+func (s *BKvStore) Run() {
+ go s.store()
+}
+
+func (s *BKvStore) Ready() <-chan struct{} {
+ return s.bready
+}
+
+func (s *BKvStore) Participant() *sstore.Indexer {
+ return s.bindexers[PARTICIPANT]
+}
+
+func (s *BKvStore) Version() *sstore.Indexer {
+ return s.bindexers[VERSION]
+}
+
+func (s *BKvStore) Pact() *sstore.Indexer {
+ return s.bindexers[PACT]
+}
+
+func (s *BKvStore) PactVersion() *sstore.Indexer {
+ return s.bindexers[PACT_VERSION]
+}
+
+func (s *BKvStore) PactTag() *sstore.Indexer {
+ return s.bindexers[PACT_TAG]
+}
+
+func (s *BKvStore) Verification() *sstore.Indexer {
+ return s.bindexers[VERIFICATION]
+}
+
+func (s *BKvStore) PactLatest() *sstore.Indexer {
+ return s.bindexers[PACT_LATEST]
+}
diff --git a/server/broker/util.go b/server/broker/util.go
new file mode 100644
index 0000000..23e98ca
--- /dev/null
+++ b/server/broker/util.go
@@ -0,0 +1,680 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 broker
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "math"
+ "net/url"
+ "strconv"
+ "strings"
+
+ "github.com/ServiceComb/paas-lager"
+ "github.com/ServiceComb/paas-lager/third_party/forked/cloudfoundry/lager"
+ "github.com/apache/incubator-servicecomb-service-center/pkg/util"
+ backend "github.com/apache/incubator-servicecomb-service-center/server/core/backend"
+ pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+ scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
+ "github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
+ serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
+)
+
+var PactLogger lager.Logger
+
+const (
+ BROKER_HOME_URL = "/"
+ BROKER_PARTICIPANTS_URL = "/participants"
+ BROKER_PARTICIPANT_URL = "/participants/:participantId"
+ BROKER_PARTY_VERSIONS_URL = "/participants/:participantId/versions"
+ BROKER_PARTY_LATEST_VERSION_URL = "/participants/:participantId/versions/latest"
+ BROKER_PARTY_VERSION_URL = "/participants/:participantId/versions/:number"
+ BROKER_PROVIDER_URL = "/pacts/provider"
+ BROKER_PROVIDER_LATEST_PACTS_URL = "/pacts/provider/:providerId/latest"
+ BROKER_PROVIDER_LATEST_PACTS_TAG_URL = "/pacts/provider/:providerId/latest/:tag"
+ BROKER_PACTS_LATEST_URL = "/pacts/latest"
+
+ BROKER_PUBLISH_URL = "/pacts/provider/:providerId/consumer/:consumerId/version/:number"
+ BROKER_PUBLISH_VERIFICATION_URL = "/pacts/provider/:providerId/consumer/:consumerId/pact-version/:pact/verification-results"
+ BROKER_WEBHOOHS_URL = "/webhooks"
+
+ BROKER_CURIES_URL = "/doc/:rel"
+)
+
+var brokerAPILinksValues = map[string]string{
+ "self": BROKER_HOME_URL,
+ "pb:publish-pact": BROKER_PUBLISH_URL,
+ "pb:latest-pact-versions": BROKER_PACTS_LATEST_URL,
+ "pb:pacticipants": BROKER_PARTICIPANTS_URL,
+ "pb:latest-provider-pacts": BROKER_PROVIDER_LATEST_PACTS_URL,
+ "pb:latest-provider-pacts-with-tag": BROKER_PROVIDER_LATEST_PACTS_TAG_URL,
+ "pb:webhooks": BROKER_WEBHOOHS_URL,
+}
+
+var brokerAPILinksTempl = map[string]bool{
+ "self": false,
+ "pb:publish-pact": true,
+ "pb:latest-pact-versions": false,
+ "pb:pacticipants": false,
+ "pb:latest-provider-pacts": true,
+ "pb:latest-provider-pacts-with-tag": true,
+ "pb:webhooks": false,
+}
+
+var brokerAPILinksTitles = map[string]string{
+ "self": "Index",
+ "pb:publish-pact": "Publish a pact",
+ "pb:latest-pact-versions": "Latest pact versions",
+ "pb:pacticipants": "Pacticipants",
+ "pb:latest-provider-pacts": "Latest pacts by provider",
+ "pb:latest-provider-pacts-with-tag": "Latest pacts by provider with a specified tag",
+ "pb:webhooks": "Webhooks",
+}
+
+func init() {
+ //define Broker logger
+ stlager.Init(stlager.Config{
+ LoggerLevel: "INFO",
+ LoggerFile: "broker_srvc.log",
+ EnableRsyslog: false,
+ })
+ PactLogger = stlager.NewLogger("broker_srvc")
+}
+
+func GetDefaultTenantProject() string {
+ return util.StringJoin([]string{"default", "default"}, "/")
+}
+
+//GenerateBrokerAPIPath creates the API link from the constant template
+func GenerateBrokerAPIPath(scheme string, host string, apiPath string,
+ replacer *strings.Replacer) string {
+ genPath := url.URL{
+ Scheme: scheme,
+ Host: host,
+ Path: apiPath,
+ }
+ if replacer != nil {
+ return replacer.Replace(genPath.String())
+ }
+ return genPath.String()
+}
+
+//GetBrokerHomeLinksAPIS return the generated Home links
+func GetBrokerHomeLinksAPIS(scheme string, host string, apiKey string) string {
+ return GenerateBrokerAPIPath(scheme, host, brokerAPILinksValues[apiKey],
+ strings.NewReplacer(":providerId", "{provider}",
+ ":consumerId", "{consumer}",
+ ":number", "{consumerApplicationVersion}",
+ ":tag", "{tag}"))
+}
+
+//CreateBrokerHomeResponse create the templated broker home response
+func CreateBrokerHomeResponse(host string, scheme string) *BrokerHomeResponse {
+
+ var apiEntries map[string]*BrokerAPIInfoEntry
+ apiEntries = make(map[string]*BrokerAPIInfoEntry)
+
+ for k := range brokerAPILinksValues {
+ apiEntries[k] = &BrokerAPIInfoEntry{
+ Href: GetBrokerHomeLinksAPIS(scheme, host, k),
+ Title: brokerAPILinksTitles[k],
+ Templated: brokerAPILinksTempl[k],
+ }
+ }
+
+ curies := []*BrokerAPIInfoEntry{}
+ curies = append(curies, &BrokerAPIInfoEntry{
+ Name: "pb",
+ Href: GenerateBrokerAPIPath(scheme, host, BROKER_CURIES_URL,
+ strings.NewReplacer(":rel", "{rel}")),
+ })
+
+ return &BrokerHomeResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "Broker Home."),
+ XLinks: apiEntries,
+ Curies: curies,
+ }
+}
+
+//GetBrokerHomeResponse gets the homeResponse from cache if it exists
+func GetBrokerHomeResponse(host string, scheme string) *BrokerHomeResponse {
+ brokerResp := CreateBrokerHomeResponse(host, scheme)
+ if brokerResp == nil {
+ return nil
+ }
+ return brokerResp
+}
+
+//GetBrokerParticipantUtils returns the participant from ETCD
+func GetBrokerParticipantUtils(ctx context.Context, tenant string, appId string,
+ serviceName string, opts ...registry.PluginOpOption) (*Participant, error) {
+
+ key := GenerateBrokerParticipantKey(tenant, appId, serviceName)
+ opts = append(opts, registry.WithStrKey(key))
+ participants, err := Store().Participant().Search(ctx, opts...)
+
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, participant with, could not be searched.")
+ return nil, err
+ }
+
+ if len(participants.Kvs) == 0 {
+ PactLogger.Info("GetParticipant found no participant")
+ return nil, nil
+ }
+
+ participant := &Participant{}
+ err = json.Unmarshal(participants.Kvs[0].Value, participant)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("GetParticipant: (%d, %s, %s)", participant.Id, participant.AppId,
+ participant.ServiceName)
+ return participant, nil
+}
+
+//GetBrokerParticipantFromServiceId returns the participant and the service from ETCD
+func GetBrokerParticipantFromServiceId(ctx context.Context, serviceId string) (*Participant,
+ *pb.MicroService, error, error) {
+
+ tenant := GetDefaultTenantProject()
+ serviceParticipant, err := serviceUtil.GetService(ctx, tenant, serviceId)
+ if err != nil {
+ PactLogger.Errorf(err,
+ "get participant failed, serviceId is %s: query provider failed.", serviceId)
+ return nil, nil, nil, err
+ }
+ if serviceParticipant == nil {
+ PactLogger.Errorf(nil,
+ "get participant failed, serviceId is %s: service not exist.", serviceId)
+ return nil, nil, nil, errors.New("get participant, serviceId not exist.")
+ }
+ // Get or create provider participant
+ participant, errBroker := GetBrokerParticipantUtils(ctx, tenant, serviceParticipant.AppId,
+ serviceParticipant.ServiceName)
+ if errBroker != nil {
+ PactLogger.Errorf(errBroker,
+ "get participant failed, serviceId %s: query participant failed.", serviceId)
+ return nil, serviceParticipant, errBroker, err
+ }
+ if participant == nil {
+ PactLogger.Errorf(nil,
+ "get participant failed, particpant does not exist for serviceId %s", serviceId)
+ return nil, serviceParticipant, errors.New("particpant does not exist for serviceId."), err
+ }
+
+ return participant, serviceParticipant, errBroker, nil
+}
+
+//GetBrokerParticipantFromService returns the participant given the microservice
+func GetBrokerParticipantFromService(ctx context.Context,
+ microservice *pb.MicroService) (*Participant, error) {
+ if microservice == nil {
+ return nil, nil
+ }
+ tenant := GetDefaultTenantProject()
+ participant, errBroker := GetBrokerParticipantUtils(ctx, tenant, microservice.AppId,
+ microservice.ServiceName)
+ if errBroker != nil {
+ PactLogger.Errorf(errBroker,
+ "get participant failed, serviceId %s: query participant failed.",
+ microservice.ServiceId)
+ return nil, errBroker
+ }
+ return participant, errBroker
+}
+
+func GetParticipant(ctx context.Context, domain string, appId string,
+ serviceName string) (*Participant, error) {
+ key := GenerateBrokerParticipantKey(domain, appId, serviceName)
+ participants, err := Store().Participant().Search(ctx, registry.WithStrKey(key))
+ if err != nil {
+ return nil, err
+ }
+ if len(participants.Kvs) == 0 {
+ PactLogger.Info("GetParticipant found no participant")
+ return nil, nil
+ }
+ participant := &Participant{}
+ err = json.Unmarshal(participants.Kvs[0].Value, participant)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("GetParticipant: (%d, %s, %s)", participant.Id, participant.AppId, participant.ServiceName)
+ return participant, nil
+}
+
+func GetVersion(ctx context.Context, domain string, number string,
+ participantId int32) (*Version, error) {
+ key := GenerateBrokerVersionKey(domain, number, participantId)
+ versions, err := Store().Version().Search(ctx, registry.WithStrKey(key))
+ if err != nil {
+ return nil, err
+ }
+ if len(versions.Kvs) == 0 {
+ return nil, nil
+ }
+ version := &Version{}
+ err = json.Unmarshal(versions.Kvs[0].Value, version)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("GetVersion: (%d, %s, %d, %d)", version.Id, version.Number, version.ParticipantId, version.Order)
+ return version, nil
+}
+
+func GetPact(ctx context.Context, domain string, consumerParticipantId int32, producerParticipantId int32, sha []byte) (*Pact, error) {
+ key := GenerateBrokerPactKey(domain, consumerParticipantId, producerParticipantId, sha)
+ versions, err := Store().Pact().Search(ctx, registry.WithStrKey(key))
+ if err != nil {
+ return nil, err
+ }
+ if len(versions.Kvs) == 0 {
+ return nil, nil
+ }
+ pact := &Pact{}
+ err = json.Unmarshal(versions.Kvs[0].Value, pact)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("GetPact: (%d, %d, %d, %s, %s)", pact.Id, pact.ConsumerParticipantId, pact.ProviderParticipantId, string(pact.Sha), string(pact.Content))
+ return pact, nil
+}
+
+func GetPactVersion(ctx context.Context, domain string, versionId int32,
+ pactId int32) (*PactVersion, error) {
+ key := GenerateBrokerPactVersionKey(domain, versionId, pactId)
+ versions, err := Store().PactVersion().Search(ctx, registry.WithStrKey(key))
+ if err != nil {
+ return nil, err
+ }
+ if len(versions.Kvs) == 0 {
+ return nil, nil
+ }
+ pactVersion := &PactVersion{}
+ err = json.Unmarshal(versions.Kvs[0].Value, pactVersion)
+ if err != nil {
+ return nil, err
+ }
+ PactLogger.Infof("GetPactVersion: (%d, %d, %d, %d)", pactVersion.Id, pactVersion.VersionId, pactVersion.PactId, pactVersion.ProviderParticipantId)
+ return pactVersion, nil
+}
+
+func GetData(ctx context.Context, key string) (int, error) {
+ values, err := Store().PactLatest().Search(ctx, registry.WithStrKey(key))
+ if err != nil {
+ return -1, err
+ }
+ if len(values.Kvs) == 0 {
+ return -1, nil
+ }
+ id, err := strconv.Atoi(string(values.Kvs[0].Value))
+ if err != nil {
+ return -1, err
+ }
+ return id, nil
+}
+
+func StoreData(ctx context.Context, key string, value string) error {
+ _, err := backend.Registry().Do(ctx, registry.PUT,
+ registry.WithStrKey(key),
+ registry.WithValue([]byte(value)))
+ return err
+}
+
+func CreateParticipant(pactLogger lager.Logger, ctx context.Context, participantKey string, participant Participant) (*PublishPactResponse, error) {
+ data, err := json.Marshal(participant)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, participant cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "participant cannot be created."),
+ }, err
+ }
+
+ _, err = backend.Registry().Do(ctx, registry.PUT,
+ registry.WithStrKey(participantKey),
+ registry.WithValue(data))
+
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, participant cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "participant cannot be created."),
+ }, err
+ }
+
+ k := GetBrokerLatestParticipantIDKey()
+ v := strconv.Itoa(int(participant.Id))
+ PactLogger.Infof("Inserting (%s, %s)", k, v)
+ err = StoreData(ctx, k, v)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, participant cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "participant cannot be created."),
+ }, err
+ }
+ PactLogger.Infof("Participant created for key: %s", participantKey)
+ return nil, nil
+}
+
+func CreateVersion(pactLogger lager.Logger, ctx context.Context, versionKey string,
+ version Version) (*PublishPactResponse, error) {
+ data, err := json.Marshal(version)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "version cannot be created."),
+ }, err
+ }
+
+ _, err = backend.Registry().Do(ctx, registry.PUT,
+ registry.WithStrKey(versionKey),
+ registry.WithValue(data))
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "version cannot be created."),
+ }, err
+ }
+ k := GetBrokerLatestVersionIDKey()
+ v := strconv.Itoa(int(version.Id))
+ PactLogger.Infof("Inserting (%s, %s)", k, v)
+ err = StoreData(ctx, k, v)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "version cannot be created."),
+ }, err
+ }
+ PactLogger.Infof("Version created for key: %s", versionKey)
+ return nil, nil
+}
+
+func CreatePact(pactLogger lager.Logger, ctx context.Context,
+ pactKey string, pact Pact) (*PublishPactResponse, error) {
+ data, err := json.Marshal(pact)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact cannot be created."),
+ }, err
+ }
+
+ _, err = backend.Registry().Do(ctx,
+ registry.PUT,
+ registry.WithStrKey(pactKey),
+ registry.WithValue(data))
+
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact cannot be created."),
+ }, err
+ }
+ k := GetBrokerLatestPactIDKey()
+ v := strconv.Itoa(int(pact.Id))
+ PactLogger.Infof("Inserting (%s, %s)", k, v)
+ err = StoreData(ctx, k, v)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact cannot be created."),
+ }, err
+ }
+ PactLogger.Infof("Pact created for key: %s", pactKey)
+ return nil, nil
+}
+
+func CreatePactVersion(pactLogger lager.Logger, ctx context.Context, pactVersionKey string, pactVersion PactVersion) (*PublishPactResponse, error) {
+ data, err := json.Marshal(pactVersion)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact version cannot be created."),
+ }, err
+ }
+
+ _, err = backend.Registry().Do(ctx,
+ registry.PUT, registry.WithValue(data), registry.WithStrKey(pactVersionKey))
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact version cannot be created."),
+ }, err
+ }
+ k := GetBrokerLatestPactVersionIDKey()
+ v := strconv.Itoa(int(pactVersion.Id))
+ PactLogger.Infof("Inserting (%s, %s)", k, v)
+ err = StoreData(ctx, k, v)
+ if err != nil {
+ PactLogger.Errorf(nil, "pact publish failed, pact version cannot be created.")
+ return &PublishPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact version cannot be created."),
+ }, err
+ }
+ PactLogger.Infof("Pact version created for key: %s", pactVersionKey)
+ return nil, nil
+}
+
+func CreateVerification(pactLogger lager.Logger, ctx context.Context,
+ verificationKey string, verification Verification) (*PublishVerificationResponse, error) {
+ data, err := json.Marshal(verification)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish failed, verification result marshal error.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "verification result marshal error."),
+ }, err
+ }
+
+ _, err = backend.Registry().Do(ctx, registry.PUT,
+ registry.WithStrKey(verificationKey),
+ registry.WithValue(data))
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish failed, verification result cannot be created.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "verification result cannot be created."),
+ }, err
+ }
+ k := GetBrokerLatestVerificationIDKey()
+ v := strconv.Itoa(int(verification.Id))
+ PactLogger.Infof("Inserting (%s, %s)", k, v)
+ err = StoreData(ctx, k, v)
+ if err != nil {
+ PactLogger.Errorf(nil, "verification result publish failed, verification result cannot be created.")
+ return &PublishVerificationResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "verification result cannot be created."),
+ }, err
+ }
+ PactLogger.Infof("Verification result created for key: %s", verificationKey)
+ return nil, nil
+}
+
+func GetLastestVersionNumberForParticipant(ctx context.Context,
+ tenant string, participantId int32) int32 {
+ key := util.StringJoin([]string{
+ GetBrokerVersionKey(tenant), ""}, "/")
+ versions, err := Store().Version().Search(ctx,
+ registry.WithStrKey(key),
+ registry.WithPrefix())
+
+ if err != nil || len(versions.Kvs) == 0 {
+ return -1
+ }
+ order := int32(math.MinInt32)
+ for i := 0; i < len(versions.Kvs); i++ {
+ version := &Version{}
+ err = json.Unmarshal(versions.Kvs[i].Value, &version)
+ if err != nil {
+ return -1
+ }
+ if version.ParticipantId != participantId {
+ continue
+ }
+ if version.Order > order {
+ order = version.Order
+ }
+ }
+ return order
+}
+
+func RetrieveProviderConsumerPact(ctx context.Context,
+ in *GetProviderConsumerVersionPactRequest) (*GetProviderConsumerVersionPactResponse, int32, error) {
+ if in == nil || len(in.ProviderId) == 0 || len(in.ConsumerId) == 0 || len(in.Version) == 0 {
+ PactLogger.Errorf(nil, "pact retrieve request failed: invalid params.")
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Request format invalid."),
+ }, -1, nil
+ }
+ tenant := GetDefaultTenantProject()
+ // Get provider microservice
+ provider, err := serviceUtil.GetService(ctx, tenant, in.ProviderId)
+ if err != nil {
+ PactLogger.Errorf(err, "pact retrieve failed, providerId is %s: query provider failed.", in.ProviderId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Query provider failed."),
+ }, -1, err
+ }
+ if provider == nil {
+ PactLogger.Errorf(nil, "pact retrieve failed, providerId is %s: provider not exist.", in.ProviderId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Provider does not exist."),
+ }, -1, nil
+ }
+ // Get consumer microservice
+ consumer, err := serviceUtil.GetService(ctx, tenant, in.ConsumerId)
+ if err != nil {
+ PactLogger.Errorf(err, "pact retrieve failed, consumerId is %s: query consumer failed.", in.ConsumerId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Query consumer failed."),
+ }, -1, err
+ }
+ if consumer == nil {
+ PactLogger.Errorf(nil, "pact retrieve failed, consumerId is %s: consumer not exist.", in.ConsumerId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Consumer does not exist."),
+ }, -1, nil
+ }
+ // Get provider participant
+ //providerParticipantKey := apt.GenerateBrokerParticipantKey(tenant, provider.AppId, provider.ServiceName)
+ providerParticipant, err := GetParticipant(ctx, tenant, provider.AppId, provider.ServiceName)
+ if err != nil || providerParticipant == nil {
+ PactLogger.Errorf(nil, "pact retrieve failed, provider participant %s cannot be searched.", in.ProviderId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "Provider participant cannot be searched."),
+ }, -1, err
+ }
+ // Get consumer participant
+ //consumerParticipantKey := apt.GenerateBrokerParticipantKey(tenant, consumer.AppId, consumer.ServiceName)
+ consumerParticipant, err := GetParticipant(ctx, tenant, consumer.AppId, consumer.ServiceName)
+ if err != nil || consumerParticipant == nil {
+ PactLogger.Errorf(nil, "pact retrieve failed, consumer participant %s cannot be searched.", in.ConsumerId)
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "consumer participant cannot be searched."),
+ }, -1, err
+ }
+ // Get or create version
+ //versionKey := apt.GenerateBrokerVersionKey(tenant, in.Version, consumerParticipant.Id)
+ version, err := GetVersion(ctx, tenant, in.Version, consumerParticipant.Id)
+ if err != nil || version == nil {
+ PactLogger.Errorf(nil, "pact retrieve failed, version cannot be searched.")
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "version cannot be searched."),
+ }, -1, err
+ }
+ // Get all pactversions and filter using the provider participant id
+ pactVersionKey := util.StringJoin([]string{
+ GetBrokerPactVersionKey(tenant),
+ strconv.Itoa(int(version.Id))},
+ "/")
+ pactVersions, err := Store().PactVersion().Search(ctx,
+ registry.WithPrefix(),
+ registry.WithStrKey(pactVersionKey))
+
+ if err != nil {
+ return nil, -1, err
+ }
+ if len(pactVersions.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPact] No pact version found, sorry")
+ return nil, -1, nil
+ }
+ pactIds := make(map[int32]int32)
+ for i := 0; i < len(pactVersions.Kvs); i++ {
+ pactVersion := &PactVersion{}
+ err = json.Unmarshal(pactVersions.Kvs[i].Value, pactVersion)
+ if err != nil {
+ return nil, -1, err
+ }
+ // Obviously true, but checking it anyways
+ if pactVersion.VersionId == version.Id {
+ pactid := pactVersion.PactId
+ pactIds[pactid] = pactid
+ }
+ }
+ if len(pactIds) == 0 {
+ PactLogger.Errorf(nil, "pact retrieve failed, pact cannot be found.")
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact cannot be found."),
+ }, -1, err
+ }
+ pactKey := util.StringJoin([]string{
+ GetBrokerPactKey(tenant),
+ strconv.Itoa(int(consumerParticipant.Id)),
+ strconv.Itoa(int(providerParticipant.Id))},
+ "/")
+ pacts, err := Store().PactVersion().Search(ctx,
+ registry.WithStrKey(pactKey),
+ registry.WithPrefix())
+
+ if err != nil {
+ return nil, -1, err
+ }
+ if len(pacts.Kvs) == 0 {
+ PactLogger.Info("[RetrieveProviderPact] No pact version found, sorry")
+ return nil, -1, nil
+ }
+ for i := 0; i < len(pacts.Kvs); i++ {
+ pactObj := &Pact{}
+ err = json.Unmarshal(pacts.Kvs[i].Value, pactObj)
+ if err != nil {
+ return nil, -1, err
+ }
+ if _, ok := pactIds[pactObj.Id]; ok {
+ //PactLogger.Infof("pact retrieve succeeded, found pact: %s", string(pactObj.Content))
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(pb.Response_SUCCESS, "pact found."),
+ Pact: pactObj.Content,
+ }, pactObj.Id, nil
+ }
+ }
+ PactLogger.Errorf(nil, "pact retrieve failed, pact cannot be found.")
+ return &GetProviderConsumerVersionPactResponse{
+ Response: pb.CreateResponse(scerr.ErrInternal, "pact cannot be found."),
+ }, -1, nil
+}
+
+func DeletePactData(ctx context.Context,
+ in *BaseBrokerRequest) (*pb.Response, error) {
+ //tenant := util.ParseTenantProject(ctx)
+ allPactKey := GetBrokerRootKey() //GetBrokerVerificationKey("default") //util.StringJoin([]string{ apt.GetRootKey(), apt.REGISTRY_PACT_ROOT_KEY }, "/")
+
+ _, err := backend.Registry().Do(ctx,
+ registry.DEL, registry.WithStrKey(allPactKey), registry.WithPrefix())
+ if err != nil {
+ return pb.CreateResponse(scerr.ErrInternal, "error deleting pacts."), err
+ }
+ return pb.CreateResponse(pb.Response_SUCCESS, "deleting pacts Succeed."), nil
+}
diff --git a/server/rest/controller/rest_util.go b/server/rest/controller/rest_util.go
index 749900b..be626d5 100644
--- a/server/rest/controller/rest_util.go
+++ b/server/rest/controller/rest_util.go
@@ -57,3 +57,15 @@ func WriteResponse(w http.ResponseWriter, resp *pb.Response, obj interface{}) {
WriteError(w, resp.GetCode(), resp.GetMessage())
}
+
+func WriteBytes(w http.ResponseWriter, resp *pb.Response, json []byte) {
+ if resp.GetCode() == pb.Response_SUCCESS {
+ w.Header().Add("X-Response-Status", fmt.Sprint(http.StatusOK))
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.WriteHeader(http.StatusOK)
+ w.Write(json)
+ return
+ }
+ WriteError(w, resp.GetCode(), resp.GetMessage())
+}
+
--
To stop receiving notification emails like this one, please contact
littlecui@apache.org.