Example #1
0
func main() {
	brokerConfigPath := configPath()

	brokerLogger := lager.NewLogger("redis-broker")
	brokerLogger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG))
	brokerLogger.RegisterSink(lager.NewWriterSink(os.Stderr, lager.ERROR))

	brokerLogger.Info("Starting CF Redis broker")

	brokerLogger.Info("Config File: " + brokerConfigPath)

	config, err := brokerconfig.ParseConfig(brokerConfigPath)
	if err != nil {
		brokerLogger.Fatal("Loading config file", err, lager.Data{
			"broker-config-path": brokerConfigPath,
		})
	}

	commandRunner := system.OSCommandRunner{
		Logger: brokerLogger,
	}

	localRepo := redis.NewLocalRepository(config.RedisConfiguration, brokerLogger)

	localRepo.AllInstancesVerbose()

	processController := &redis.OSProcessController{
		CommandRunner:            commandRunner,
		InstanceInformer:         localRepo,
		Logger:                   brokerLogger,
		ProcessChecker:           &process.ProcessChecker{},
		ProcessKiller:            &process.ProcessKiller{},
		PingFunc:                 redis.PingServer,
		WaitUntilConnectableFunc: availability.Check,
	}

	localCreator := &redis.LocalInstanceCreator{
		FindFreePort:            system.FindFreePort,
		RedisConfiguration:      config.RedisConfiguration,
		ProcessController:       processController,
		LocalInstanceRepository: localRepo,
	}

	agentClient := &redis.RemoteAgentClient{
		HttpAuth: config.AuthConfiguration,
	}
	remoteRepo, err := redis.NewRemoteRepository(agentClient, config, brokerLogger)
	if err != nil {
		brokerLogger.Fatal("Error initializing remote repository", err)
	}

	sigChannel := make(chan os.Signal, 1)
	signal.Notify(sigChannel, syscall.SIGTERM)
	go func() {
		<-sigChannel
		brokerLogger.Info("Starting Redis Broker shutdown")
		localRepo.AllInstancesVerbose()
		remoteRepo.StateFromFile()
		os.Exit(0)
	}()

	serviceBroker := &broker.RedisServiceBroker{
		InstanceCreators: map[string]broker.InstanceCreator{
			"shared":    localCreator,
			"dedicated": remoteRepo,
		},
		InstanceBinders: map[string]broker.InstanceBinder{
			"shared":    localRepo,
			"dedicated": remoteRepo,
		},
		Config: config,
	}

	brokerCredentials := brokerapi.BrokerCredentials{
		Username: config.AuthConfiguration.Username,
		Password: config.AuthConfiguration.Password,
	}

	brokerAPI := brokerapi.New(serviceBroker, brokerLogger, brokerCredentials)

	authWrapper := auth.NewWrapper(brokerCredentials.Username, brokerCredentials.Password)
	debugHandler := authWrapper.WrapFunc(debug.NewHandler(remoteRepo))
	instanceHandler := authWrapper.WrapFunc(redisinstance.NewHandler(remoteRepo))

	http.HandleFunc("/instance", instanceHandler)
	http.HandleFunc("/debug", debugHandler)
	http.Handle("/", brokerAPI)

	brokerLogger.Fatal("http-listen", http.ListenAndServe(config.Host+":"+config.Port, nil))
}
		var err error
		tmpDir, err = ioutil.TempDir("", "cf-redis-broker")
		Expect(err).ToNot(HaveOccurred())

		fakeAgentClient = &fakes.FakeAgentClient{}
		fakeAgentClient.CredentialsFunc = func(rootURL string) (redis.Credentials, error) {
			return redis.Credentials{
				Port:     6666,
				Password: "******",
			}, nil
		}

		statefilePath = path.Join(tmpDir, "statefile.json")
		config.RedisConfiguration.Dedicated.StatefilePath = statefilePath
		repo, err = redis.NewRemoteRepository(fakeAgentClient, config, logger)
		Expect(err).ToNot(HaveOccurred())
	})

	Describe("NewRemoteRepository", func() {
		Context("When a state file does not exist", func() {
			It("logs statefile creation", func() {
				Expect(logger).To(gbytes.Say(fmt.Sprintf("statefile %s not found, generating instead", statefilePath)))
			})

			It("logs 0 dedicated instances found", func() {
				Expect(logger).To(gbytes.Say("0 dedicated Redis instances found"))
			})
		})

		Context("When a state file exists", func() {
	helpers.ResetTestDirs()

	dirs = []string{"/tmp/to/redis", "/tmp/redis/data/directory", "/tmp/redis/log/directory"}
	for _, dir := range dirs {
		err := os.MkdirAll(dir, 0755)
		Ω(err).ShouldNot(HaveOccurred())
	}
	_, err := os.Create("/tmp/to/redis/config.conf")
	Ω(err).ShouldNot(HaveOccurred())
	path, err := filepath.Abs(path.Join("..", "brokerconfig", "assets", "test_config.yml"))
	Ω(err).ToNot(HaveOccurred())
	config, err := brokerconfig.ParseConfig(path)
	Ω(err).NotTo(HaveOccurred())

	logger := lager.NewLogger("foo")
	repo, err := redis.NewRemoteRepository(&redis.RemoteAgentClient{}, config, logger)
	Ω(err).NotTo(HaveOccurred())

	handler := debug.NewHandler(repo)

	http.HandleFunc("/debug", handler)
	go func() {
		defer GinkgoRecover()
		err := http.ListenAndServe("localhost:3000", nil)
		Expect(err).ToNot(HaveOccurred())
	}()

	client := http.Client{}
	for i := 0; i < 10; i++ {
		_, err = client.Get("http://localhost:3000/debug")
		if err == nil {
		var err error
		tmpDir, err = ioutil.TempDir("", "cf-redis-broker")
		Expect(err).ToNot(HaveOccurred())

		fakeAgentClient = &fakes.FakeAgentClient{}
		fakeAgentClient.CredentialsFunc = func(rootURL string) (redis.Credentials, error) {
			return redis.Credentials{
				Port:     6666,
				Password: "******",
			}, nil
		}

		statefilePath = path.Join(tmpDir, "statefile.json")
		config.RedisConfiguration.Dedicated.StatefilePath = statefilePath
		repo, err = redis.NewRemoteRepository(fakeAgentClient, config)
		Expect(err).ToNot(HaveOccurred())
	})

	Describe("NewRemoteRepository", func() {
		Context("When a state file does not exist", func() {
			It("does not return an error", func() {
				_, err := redis.NewRemoteRepository(fakeAgentClient, config)
				Expect(err).ToNot(HaveOccurred())
			})
		})

		Context("When a state file exists", func() {
			var statefile Statefile

			BeforeEach(func() {