func setupServer(t *testing.T, rest_port, rep_port uint16, cl cluster.Cluster) (replication.Replication, api.Server) { var rep replication.Replication var server api.Server networkAvailable := network.WaitForPrivateNetwork() assert.NotNil(t, networkAvailable) // Configure and create the cluster module if cl == nil { return nil, nil } var err error // Configure and create the replication module self := cluster.NewMember(network.GetPrivateIP(), rep_port) repConfig := &replication.Config{ Membership: cl.Membership(), Registrator: cl.Registrator(self), } rep, err = replication.New(repConfig) assert.NoError(t, err) assert.NotNil(t, rep) regConfig := &store.Config{ DefaultTTL: time.Duration(30) * time.Second, MinimumTTL: time.Duration(10) * time.Second, MaximumTTL: time.Duration(600) * time.Second, SyncWaitTime: time.Duration(defaultSyncWaitTime) * time.Second, NamespaceCapacity: 50, } reg := store.New(regConfig, rep) server, err = api.NewServer( &api.Config{ HTTPAddressSpec: fmt.Sprintf(":%d", rest_port), Registry: reg, }, ) assert.NoError(t, err) assert.NotNil(t, server) // Start the API server, and "wait" for it to bind go server.Start() time.Sleep(100 * time.Millisecond) return rep, server }
func createMember(port uint16) cluster.Member { return cluster.NewMember(network.GetPrivateIP(), port) }
func TestGzippedReplication(t *testing.T) { if testing.Short() { t.Skip() } cluster := createCluster() member1 := createMember(6106) repServer1, _ := New(&Config{ Registrator: cluster.Registrator(member1), Membership: cluster.Membership()}) defer repServer1.Stop() <-repServer1.Sync(1) member2 := createMember(6206) repServer2, _ := New(&Config{ Registrator: cluster.Registrator(member2), Membership: cluster.Membership()}) defer repServer2.Stop() <-repServer2.Sync(1) var resp *http.Response replicator2, _ := repServer2.GetReplicator(auth.NamespaceFrom("ns1")) client := http.Client{Transport: &http.Transport{MaxIdleConnsPerHost: 1}} var requestData bytes.Buffer for i := 0; i < 100; i++ { requestData.Write([]byte("9999999999999999999999999999999999")) } // Iterate over both sync and replication HTTP endpoints for _, serviceType := range []string{syncContext, repContext} { // Iterate over both content-encoding options- gzip and no zip (identity) for _, encoding := range []string{"gzip", "identity"} { var dec decoder var unZipper *gzip.Reader var respBuff bytes.Buffer // prepare event that triggers a replication or a sync if serviceType == repContext { time.AfterFunc(time.Duration(2)*time.Second, func() { replicator2.Broadcast(requestData.Bytes()) }) } else { // grab the channel that was created for us // insert an entity inside it and close the channel to signal sync finish outMsg := &outMessage{Data: requestData.Bytes()} buff, _ := json.Marshal(outMsg) time.AfterFunc(time.Duration(2)*time.Second, func() { ch := <-repServer2.SyncRequest() ch <- buff close(ch) }) } url := fmt.Sprintf("http://%s:%d/%s/%s", network.GetPrivateIP(), 6206, version, serviceType) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Accept-Encoding", encoding) req.Header.Set(headerMemberID, "fake member id") resp, _ = client.Do(req) // wait 4 sec to read enough data, since ioutil.ReadAll blocks until EOF // and we use an indefinite connection in case of replication service endpoint if serviceType == repContext { time.AfterFunc(time.Duration(4)*time.Second, func() { resp.Body.Close() }) } responseData, _ := ioutil.ReadAll(resp.Body) respBuff.Write(responseData) // if we've sent a gzipped entity, decode it before comparing // but also ensure that the returned payload was compressed // by comparing the size of the payload to the size sent if encoding == "gzip" { assert.True(t, len(requestData.Bytes()) > len(responseData), "Seems like the gzip hasn't shrunk the payload size enough or at all") unZipper, _ = gzip.NewReader(&respBuff) dec.Reader = bufio.NewReader(unZipper) } else { dec.Reader = bufio.NewReader(&respBuff) } event, _ := dec.Decode() if encoding == "gzip" { unZipper.Close() } var entityFromServer outMessage json.Unmarshal([]byte(event.Data()), &entityFromServer) assert.Equal(t, string(requestData.Bytes()), string(entityFromServer.Data), "Didn't receive the same content we sent in the case where encoding is %s", encoding) } } }
// registryMain is the logical entry point for the service registry. func registryMain(conf *config.Values) error { // Configure logging parsedLogLevel, err := logrus.ParseLevel(conf.LogLevel) if err != nil { return err } logrus.SetLevel(parsedLogLevel) formatter, err := logging.GetLogFormatter(conf.LogFormat) if err != nil { return err } logrus.SetFormatter(formatter) // Configure locales and translations err = i18n.LoadLocales("./locales") if err != nil { return err } var rep replication.Replication if conf.Replication { // Wait for private network to become available // In some cloud environments, that may take several seconds networkAvailable := network.WaitForPrivateNetwork() if !networkAvailable { return fmt.Errorf("No private network is available within defined timeout") } // Configure and create the cluster module clConfig := &cluster.Config{ BackendType: cluster.FilesystemBackend, Directory: conf.ClusterDirectory, Size: conf.ClusterSize, } cl, err := cluster.New(clConfig) if err != nil { return fmt.Errorf("Failed to create the cluster module: %s", err) } // Configure and create the replication module self := cluster.NewMember(network.GetPrivateIP(), conf.ReplicationPort) repConfig := &replication.Config{ Membership: cl.Membership(), Registrator: cl.Registrator(self), } rep, err = replication.New(repConfig) if err != nil { return fmt.Errorf("Failed to create the replication module: %s", err) } } var authenticator auth.Authenticator if len(conf.AuthModes) > 0 { auths := make([]auth.Authenticator, len(conf.AuthModes)) for i, mode := range conf.AuthModes { switch mode { case "trusted": auths[i] = auth.NewTrustedAuthenticator() case "jwt": jwtAuth, err := auth.NewJWTAuthenticator([]byte(conf.JWTSecret)) if err != nil { return fmt.Errorf("Failed to create the authentication module: %s", err) } auths[i] = jwtAuth default: return fmt.Errorf("Failed to create the authentication module: unrecognized authentication mode '%s'", err) } } authenticator, err = auth.NewChainAuthenticator(auths) if err != nil { return err } } else { authenticator = auth.DefaultAuthenticator() } regConfig := &store.Config{ DefaultTTL: conf.DefaultTTL, MinimumTTL: conf.MinTTL, MaximumTTL: conf.MaxTTL, SyncWaitTime: conf.SyncTimeout, NamespaceCapacity: conf.NamespaceCapacity, } reg := store.New(regConfig, rep) serverConfig := &api.Config{ HTTPAddressSpec: fmt.Sprintf(":%d", conf.APIPort), Registry: reg, Authenticator: authenticator, RequireHTTPS: conf.RequireHTTPS, } server, err := api.NewServer(serverConfig) if err != nil { return err } go metrics.DumpPeriodically() return server.Start() }