github.com/canhui/fabric_ca2_2@v2.0.0-alpha+incompatible/test/fabric-ca-load-tester/testClient.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package main 17 18 import ( 19 "bytes" 20 "fmt" 21 "log" 22 23 "github.com/hyperledger/fabric-ca/api" 24 "github.com/hyperledger/fabric-ca/lib" 25 ) 26 27 // testClient represents an application using the fabric-ca client 28 type testClient struct { 29 id int 30 FabClient *lib.Client 31 Identity *lib.Identity 32 numTests int 33 res testClientRes 34 } 35 36 // testClientRes represents a response returned by the TestClient 37 // after it completes running all the tests 38 type testClientRes struct { 39 clientID int 40 numTests int 41 numErrors int 42 errs []string 43 } 44 45 func (c *testClient) runTests(fin chan testClientRes) { 46 c.res = testClientRes{ 47 clientID: c.id, 48 numErrors: 0, 49 errs: make([]string, 0, 1), 50 } 51 iter := 0 52 for { 53 it := getIdentityType(iter) 54 iter++ 55 eid, err := genEnrollmentID(it) 56 if err != nil { 57 log.Printf("Failed to get enrollment ID: %v", err) 58 continue 59 } 60 c.runTestSuite(eid) 61 if c.numTests >= testCfg.NumReqsPerUser { 62 c.res.numTests = c.numTests 63 fin <- c.res 64 break 65 } 66 } 67 } 68 69 // Stringify TestClientRes 70 func (cr testClientRes) String() string { 71 var buffer bytes.Buffer 72 buffer.WriteString(fmt.Sprintf("Client %d finished with %d errors, after running %d tests", 73 cr.clientID, cr.numErrors, cr.numTests)) 74 if cr.errs != nil && len(cr.errs) > 0 { 75 buffer.WriteString("\n errors:\n") 76 for _, errStr := range cr.errs { 77 buffer.WriteString(" " + errStr + "\n") 78 } 79 } 80 return buffer.String() 81 } 82 83 func (c *testClient) runTestSuite(eid *enrollmentID) { 84 var enrRes lib.EnrollmentResponse 85 suite: 86 for _, test := range testCfg.TestSeq { 87 i := 0 88 for { 89 err := c.runTest(test, eid, &enrRes) 90 if err != nil { 91 c.res.numErrors++ 92 c.res.errs = append(c.res.errs, err.Error()) 93 break suite 94 } 95 c.numTests++ 96 if test.Repeat <= 0 || i == test.Repeat { 97 break 98 } 99 i++ 100 } 101 } 102 } 103 104 func (c *testClient) runTest(test Test, eid *enrollmentID, enrRes *lib.EnrollmentResponse) (err error) { 105 switch test.Name { 106 case "enroll": 107 _, err = c.enrollOnly(test.Req) 108 if err != nil { 109 log.Printf("Failed to enroll identity %s: %v", *eid.ID, err) 110 } 111 case "register": 112 _, err = c.register(eid, getAffiliation()) 113 if err != nil { 114 log.Printf("Failed to register identity %s: %v", *eid.ID, err) 115 } 116 case "re-enroll": 117 err = c.reenroll(enrRes.Identity) 118 if err != nil { 119 log.Printf("Failed to reenroll identity %s: %v", *eid.ID, err) 120 } 121 case "get-tcerts": 122 err = c.getTCerts(test.Req, enrRes.Identity) 123 if err != nil { 124 log.Printf("Failed to get TCert batch for identity %s: %v", *eid.ID, err) 125 } 126 case "revoke": 127 err = c.revoke(test.Req, enrRes.Identity, "") 128 if err != nil { 129 log.Printf("Failed to revoke identity %s: %v", *eid.ID, err) 130 } 131 case "get-cacert": 132 err = c.getCACert() 133 if err != nil { 134 log.Printf("Failed to get CA certificate: %v", err) 135 } 136 default: 137 var r *lib.EnrollmentResponse 138 r, err = c.registerAndEnroll(eid, getAffiliation()) 139 if err != nil { 140 log.Printf("Failed to enroll identity %s: %v", *eid.ID, err) 141 } else { 142 *enrRes = *r 143 } 144 } 145 return 146 } 147 148 // Registers the specified identity 149 func (c *testClient) register(eid *enrollmentID, afl string) (resp *api.RegistrationResponse, err error) { 150 regReq := api.RegistrationRequest{ 151 Name: *eid.ID, 152 Type: string(*eid.it), 153 Affiliation: afl, 154 MaxEnrollments: 2, 155 } 156 resp, err = c.Identity.Register(®Req) 157 if err != nil { 158 return 159 } 160 log.Printf("Successfully registered identity %s: %+v", *eid.ID, resp) 161 return 162 } 163 164 // Enrolls the specified identity 165 func (c *testClient) enrollOnly(req TestRequest) (enrRes *lib.EnrollmentResponse, err error) { 166 csr := c.FabClient.Config.CSR 167 enrollReq := req.getEnrollmentReq() 168 if enrollReq.CSR == nil { 169 csr.CN = enrollReq.Name 170 enrollReq.CSR = &csr 171 } 172 enrRes, err = c.FabClient.Enroll(enrollReq) 173 if enrRes != nil { 174 log.Printf("Successfully enrolled identity: %s", enrollReq.Name) 175 } 176 return 177 } 178 179 // Enrolls the specified identity 180 func (c *testClient) enroll(eid *enrollmentID, pass string) (enrRes *lib.EnrollmentResponse, err error) { 181 csr := c.FabClient.Config.CSR 182 csr.CN = *eid.ID 183 enrollReq := api.EnrollmentRequest{ 184 Name: *eid.ID, 185 Secret: pass, 186 CSR: &csr, 187 } 188 enrRes, err = c.FabClient.Enroll(&enrollReq) 189 if enrRes != nil { 190 log.Printf("Successfully enrolled identity: %s", *eid.ID) 191 } 192 return 193 } 194 195 func (c *testClient) registerAndEnroll(eid *enrollmentID, afl string) (enrRes *lib.EnrollmentResponse, err error) { 196 var regRes *api.RegistrationResponse 197 regRes, err = c.register(eid, afl) 198 if regRes != nil { 199 enrRes, err = c.enroll(eid, regRes.Secret) 200 if err == nil { 201 log.Printf("Successfully registered and enrolled identity: %s", *eid.ID) 202 } 203 } 204 return 205 } 206 207 // Returns TCert batch for the specified identity 208 func (c *testClient) getTCerts(req TestRequest, id *lib.Identity) error { 209 var tcertReq *api.GetTCertBatchRequest 210 if req != nil { 211 tcertReq = req.getTCertsReq() 212 } else { 213 tcertReq = &api.GetTCertBatchRequest{ 214 Count: 1, 215 DisableKeyDerivation: true, 216 EncryptAttrs: true, 217 } 218 } 219 if tcertReq.PreKey == "" { 220 tcertReq.PreKey = id.GetName() 221 } 222 _, err := id.GetTCertBatch(tcertReq) 223 if err == nil { 224 log.Printf("Successfully retrieved TCert batch %d for the idenity: %s", 225 tcertReq.Count, id.GetName()) 226 } 227 return err 228 } 229 230 // Re-enrolls the specified identity 231 func (c *testClient) reenroll(id *lib.Identity) error { 232 csr := c.FabClient.Config.CSR 233 enrRes, err := id.Reenroll(&api.ReenrollmentRequest{ 234 CSR: &csr, 235 }) 236 if enrRes != nil { 237 log.Printf("Successfully re-enrolled identity: %s", id.GetName()) 238 } 239 return err 240 } 241 242 // Revokes the specified identity 243 func (c *testClient) revoke(req TestRequest, id *lib.Identity, reason string) (err error) { 244 if c.Identity == nil { 245 c.Identity, err = c.FabClient.LoadMyIdentity() 246 if err != nil { 247 return 248 } 249 } 250 251 revokeReq := &api.RevocationRequest{} 252 if reason != "" { 253 revokeReq.Reason = reason 254 } 255 var serial, aki, msg string 256 serial, aki, err = lib.GetCertID(id.GetECert().Cert()) 257 if req["Name"] != "" { 258 revokeReq.Name = id.GetName() 259 msg = fmt.Sprintf("Successfully revoked Identity: %s", id.GetName()) 260 } else { 261 if err != nil { 262 return 263 } 264 msg = fmt.Sprintf("Successfully revoked ECert %s of Identity: %s", aki, id.GetName()) 265 revokeReq.AKI = aki 266 revokeReq.Serial = serial 267 } 268 result, err := c.Identity.Revoke(revokeReq) 269 log.Printf("Sucessfully revoked certificates: %+v", result.RevokedCerts) 270 if err == nil { 271 log.Printf(msg) 272 } 273 return 274 } 275 276 // Gets CA root of the fabric-ca-server 277 func (c *testClient) getCACert() error { 278 req := api.GetCAInfoRequest{ 279 CAName: "", 280 } 281 _, err := c.FabClient.GetCAInfo(&req) 282 if err != nil { 283 return err 284 } 285 log.Println("Successfully retrieved CA certificate") 286 return err 287 } 288 289 func getTestClient(id int, configHome *string, cfg *lib.ClientConfig, i *lib.Identity) *testClient { 290 return &testClient{ 291 id: id, 292 FabClient: &lib.Client{ 293 HomeDir: *configHome, 294 Config: cfg, 295 }, 296 Identity: i, 297 } 298 }