1
1
package storage
2
2
3
3
import (
4
- _ "github.com/go-kivik/couchdb/v3" // The CouchDB Driver
4
+ "github.com/go-kivik/couchdb/v3" // The CouchDB Driver
5
+ "github.com/go-kivik/couchdb/v3/chttp"
5
6
kivik "github.com/go-kivik/kivik/v3"
6
7
"strings"
7
8
9
+ "bytes"
8
10
"context"
9
- // "crypto/tls"
10
- // "crypto/x509"
11
+ "crypto/tls"
12
+ "crypto/x509"
11
13
"fmt"
12
14
"io"
13
15
"io/ioutil"
14
- //"net/http"
15
- //"os"
16
- "bytes"
16
+ "net/http"
17
+ "os"
17
18
"time"
18
19
19
20
"github.com/open-horizon/edge-sync-service/common"
@@ -96,66 +97,59 @@ func (store *CouchStorage) Init() common.SyncServiceError {
96
97
"Password" : common .Configuration .CouchPassword ,
97
98
}
98
99
99
- store .dsn = createDSN (store .loginInfo ["ipAddress" ], store . loginInfo [ "Username" ], store . loginInfo [ "Password" ] )
100
+ store .dsn = createDSN (store .loginInfo ["ipAddress" ])
100
101
var client * kivik.Client
101
102
var err error
102
103
103
- // if common.Configuration.CouchUseSSL {
104
- // tlsConfig := &tls.Config{}
105
- // if common.Configuration.CouchCACertificate != "" {
106
- // var caFile string
107
- // if strings.HasPrefix(common.Configuration.CouchCACertificate, "/") {
108
- // caFile = common.Configuration.CouchCACertificate
109
- // } else {
110
- // caFile = common.Configuration.PersistenceRootPath + common.Configuration.CouchCACertificate
111
- // }
112
- // serverCaCert, err := ioutil.ReadFile(caFile)
113
- // if err != nil {
114
- // if _, ok := err.(*os.PathError); ok {
115
- // serverCaCert = []byte(common.Configuration.CouchCACertificate)
116
- // err = nil
117
- // } else {
118
- // message := fmt.Sprintf("Failed to find couch SSL CA file. Error: %s.", err)
119
- // return &Error{message}
120
- // }
121
- // }
122
-
123
- // caCertPool := x509.NewCertPool()
124
- // caCertPool.AppendCertsFromPEM(serverCaCert)
125
- // tlsConfig.RootCAs = caCertPool
126
- // }
127
-
128
- // // Please avoid using this if possible! Makes using TLS pointless
129
- // if common.Configuration.CouchAllowInvalidCertificates {
130
- // tlsConfig.InsecureSkipVerify = true
131
- // }
132
-
133
- // setXport := couchdb.SetTransport(&http.Transport{TLSClientConfig: tlsConfig})
134
- // client, err = kivik.New("couch", store.dsn)
135
- // if err != nil {
136
- // message := fmt.Sprintf("Failed to connect. Error: %s.", err)
137
- // return &Error{message}
138
- // }
139
-
140
- // err = client.Authenticate(context.TODO(), setXport)
141
- // if err != nil {
142
- // message := fmt.Sprintf("Authentication Failed. Error: %s.", err)
143
- // return &Error{message}
144
- // }
145
- //}
146
-
147
- // basicAuth := couchdb.BasicAuth(store.loginInfo["Username"], store.loginInfo["Password"])
148
- // err = client.Authenticate(context.TODO(), basicAuth)
149
- // if err != nil {
150
- // return err
151
- // }
152
-
153
104
client , err = kivik .New ("couch" , store .dsn )
154
105
if client == nil || err != nil {
155
106
message := fmt .Sprintf ("Failed to connect to couch. Error: %s." , err )
156
107
return & Error {message }
157
108
}
158
109
110
+ if common .Configuration .CouchUseSSL {
111
+ tlsConfig := & tls.Config {}
112
+ if common .Configuration .CouchCACertificate != "" {
113
+ var caFile string
114
+ if strings .HasPrefix (common .Configuration .CouchCACertificate , "/" ) {
115
+ caFile = common .Configuration .CouchCACertificate
116
+ } else {
117
+ caFile = common .Configuration .PersistenceRootPath + common .Configuration .CouchCACertificate
118
+ }
119
+ serverCaCert , err := ioutil .ReadFile (caFile )
120
+ if err != nil {
121
+ if _ , ok := err .(* os.PathError ); ok {
122
+ serverCaCert = []byte (common .Configuration .CouchCACertificate )
123
+ err = nil
124
+ } else {
125
+ message := fmt .Sprintf ("Failed to find Couch SSL CA file. Error: %s." , err )
126
+ return & Error {message }
127
+ }
128
+ }
129
+
130
+ caCertPool := x509 .NewCertPool ()
131
+ caCertPool .AppendCertsFromPEM (serverCaCert )
132
+ tlsConfig .RootCAs = caCertPool
133
+ }
134
+
135
+ // Please avoid using this if possible! Makes using TLS pointless
136
+ if common .Configuration .CouchAllowInvalidCertificates {
137
+ tlsConfig .InsecureSkipVerify = true
138
+ }
139
+
140
+ setXport := couchdb .SetTransport (& http.Transport {TLSClientConfig : tlsConfig })
141
+ err = client .Authenticate (context .TODO (), setXport )
142
+ if err != nil {
143
+ message := fmt .Sprintf ("Authentication Failed. Error: %s." , err )
144
+ return & Error {message }
145
+ }
146
+ }
147
+
148
+ err = client .Authenticate (context .TODO (), & chttp.BasicAuth {Username : store .loginInfo ["Username" ], Password : store .loginInfo ["Password" ]})
149
+ if err != nil {
150
+ return err
151
+ }
152
+
159
153
available , err := client .Ping (context .TODO ())
160
154
if ! available || err != nil {
161
155
return err
@@ -271,6 +265,9 @@ func (store *CouchStorage) StoreObject(metaData common.MetaData, data []byte, st
271
265
RemainingConsumers : metaData .ExpectedConsumers ,
272
266
RemainingReceivers : metaData .ExpectedConsumers , Destinations : dests }
273
267
268
+ // In case of existing object, check if it had attachment and add to newObject if present
269
+ // This is done only in case of metaOnly update
270
+ // otherwise updated attachment will be added in the next block
274
271
if existingObject != nil {
275
272
newObject .Rev = existingObject .Rev
276
273
if metaData .MetaOnly && data == nil {
@@ -286,6 +283,7 @@ func (store *CouchStorage) StoreObject(metaData common.MetaData, data []byte, st
286
283
}
287
284
}
288
285
286
+ // Add attachment to newObject for NoData=false
289
287
if ! metaData .NoData && data != nil {
290
288
content := ioutil .NopCloser (bytes .NewReader (data ))
291
289
defer content .Close ()
@@ -295,6 +293,8 @@ func (store *CouchStorage) StoreObject(metaData common.MetaData, data []byte, st
295
293
newObject .Attachments = attachments
296
294
}
297
295
296
+ // Cases where attachment needs to be removed are handled implicitly
297
+ // by not adding the existing attachment to newObject
298
298
if err := store .upsertObject (id , newObject ); err != nil {
299
299
return nil , & Error {fmt .Sprintf ("Failed to store an object. Error: %s." , err )}
300
300
}
0 commit comments