@@ -2,6 +2,7 @@ package util
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
5
6
"fmt"
6
7
"net/http"
7
8
"strings"
@@ -93,24 +94,10 @@ func GetServiceIDByName(c rest.FrontClient, name string) (akid.ServiceID, error)
93
94
return akid.ServiceID {}, errors .Errorf ("cannot determine project ID for %s" , name )
94
95
}
95
96
96
- func GetServiceIDByPostmanCollectionID (c rest.FrontClient , collectionID string ) (akid.ServiceID , error ) {
97
- // Normalize the collectionID.
98
- collectionID = strings .ToLower (collectionID )
99
- unexpectedErrMsg := "Something went wrong while starting the Agent. " +
100
- "Please contact Postman support (observability-support@postman.com) with the error details"
101
-
102
- if id , found := postmanCollectionIDCache .Get (collectionID ); found {
103
- printer .Stderr .Debugf ("Cached collectionID %q is %q\n " , collectionID , akid .String (id .(akid.ServiceID )))
104
- return id .(akid.ServiceID ), nil
105
- }
106
-
107
- // Fill cache.
108
- ctx , cancel := context .WithTimeout (context .Background (), apiTimeout )
109
- defer cancel ()
97
+ func GetServiceIDByPostmanCollectionID (c rest.FrontClient , ctx context.Context , collectionID string ) (akid.ServiceID , error ) {
110
98
services , err := c .GetServices (ctx )
111
99
if err != nil {
112
- printer .Stderr .Debugf ("Failed to get list of services associated with the API Key: %s\n " , err )
113
- return akid.ServiceID {}, errors .Wrap (err , unexpectedErrMsg )
100
+ return akid.ServiceID {}, err
114
101
}
115
102
116
103
var result akid.ServiceID
@@ -128,24 +115,72 @@ func GetServiceIDByPostmanCollectionID(c rest.FrontClient, collectionID string)
128
115
129
116
if strings .EqualFold (collectionID , svcCollectionID ) {
130
117
result = svc .ID
131
- postmanCollectionIDCache .Set (svcCollectionID , svc .ID , cache .DefaultExpiration )
132
118
}
133
119
}
134
120
135
- if (result != akid.ServiceID {}) {
136
- printer .Stderr .Debugf ("Postman collectionID %q is %q\n " , collectionID , result )
137
- return result , nil
121
+ return result , nil
122
+ }
123
+
124
+ func GetOrCreateServiceIDByPostmanCollectionID (c rest.FrontClient , collectionID string ) (akid.ServiceID , error ) {
125
+ // Normalize the collectionID.
126
+ collectionID = strings .ToLower (collectionID )
127
+ unexpectedErrMsg := "Something went wrong while starting the Agent. " +
128
+ "Please contact Postman support (observability-support@postman.com) with the error details"
129
+ failedToCreateServiceErrMsg := "Failed to create service for given collectionID: %s\n "
130
+
131
+ if id , found := postmanCollectionIDCache .Get (collectionID ); found {
132
+ printer .Stderr .Debugf ("Cached collectionID %q is %q\n " , collectionID , akid .String (id .(akid.ServiceID )))
133
+ return id .(akid.ServiceID ), nil
134
+ }
135
+
136
+ // Fetch service and fill cache
137
+ ctx , cancel := context .WithTimeout (context .Background (), apiTimeout )
138
+ defer cancel ()
139
+
140
+ serviceID , err := GetServiceIDByPostmanCollectionID (c , ctx , collectionID )
141
+ if err != nil {
142
+ printer .Stderr .Debugf ("Failed to get list of services associated with the API Key: %s\n " , err )
143
+ return akid.ServiceID {}, errors .Wrap (err , unexpectedErrMsg )
144
+ }
145
+
146
+ if (serviceID != akid.ServiceID {}) {
147
+ printer .Stderr .Debugf ("ServiceID for Postman collectionID %q is %q\n " , collectionID , serviceID )
148
+ postmanCollectionIDCache .Set (collectionID , serviceID , cache .DefaultExpiration )
149
+ return serviceID , nil
138
150
}
139
151
140
152
name := postmanRandomName ()
141
153
printer .Debugf ("Found no service for given collectionID: %s, creating a new service %q\n " , collectionID , name )
142
154
// Create service for given postman collectionID
143
155
resp , err := c .CreateService (ctx , name , collectionID )
144
156
if err != nil {
145
- printer .Stderr .Debugf ("Failed to create service for given collectionID: %s\n " , err )
157
+ httpErr , ok := err .(rest.HTTPError )
158
+ if ! ok {
159
+ printer .Stderr .Debugf (failedToCreateServiceErrMsg , err )
160
+ return akid.ServiceID {}, errors .Wrap (err , unexpectedErrMsg )
161
+ }
162
+
163
+ var errorResponse rest.CreateServiceErrorResponse
164
+ if err := json .Unmarshal (httpErr .Body , & errorResponse ); err != nil {
165
+ printer .Stderr .Debugf (failedToCreateServiceErrMsg , err )
166
+ return akid.ServiceID {}, errors .Wrap (err , unexpectedErrMsg )
167
+ }
146
168
147
- if httpErr , ok := err .(rest.HTTPError ); ok && httpErr .StatusCode == 403 {
148
- error := fmt .Errorf ("You cannot send traffic to the collection with ID %s. " +
169
+ if httpErr .StatusCode == 409 && errorResponse .Message == "collection_already_mapped" {
170
+ serviceID , err := GetServiceIDByPostmanCollectionID (c , ctx , collectionID )
171
+ if err != nil {
172
+ printer .Stderr .Debugf (failedToCreateServiceErrMsg , err )
173
+ return akid.ServiceID {}, errors .Wrap (err , unexpectedErrMsg )
174
+ }
175
+
176
+ if (serviceID != akid.ServiceID {}) {
177
+ printer .Stderr .Debugf ("ServiceID for Postman collectionID %q is %q\n " , collectionID , serviceID )
178
+ postmanCollectionIDCache .Set (collectionID , serviceID , cache .DefaultExpiration )
179
+ return serviceID , nil
180
+ }
181
+
182
+ } else if httpErr .StatusCode == 403 {
183
+ error := fmt .Errorf ("you cannot send traffic to the collection with ID %s. " +
149
184
"Ensure that your collection ID is correct and that you have edit permissions on the collection. " +
150
185
"If you do not have edit permissions, please contact the workspace administrator to add you as a collection editor." , collectionID )
151
186
return akid.ServiceID {}, error
@@ -155,6 +190,7 @@ func GetServiceIDByPostmanCollectionID(c rest.FrontClient, collectionID string)
155
190
}
156
191
157
192
printer .Debugf ("Got service ID %s\n " , resp .ResourceID )
193
+ postmanCollectionIDCache .Set (collectionID , resp .ResourceID , cache .DefaultExpiration )
158
194
159
195
return resp .ResourceID , nil
160
196
}
0 commit comments