Beispiel #1
0
// SetMandrill sets the Mandrill API for sending emails. This function is not
// recursive and returns nil. @todo
func SetMandrill(opts ...MandrillOptions) DaemonOption {
	return func(da *Daemon) DaemonOption {
		// this whole func is just a quick write down. no idea if it's working
		// and refactor ... 8-)
		apiKey := da.Config.GetString(config.ScopeStore(da.ScopeID), config.Path(PathSmtpMandrillAPIKey))

		if apiKey == "" {
			da.lastErrs = append(da.lastErrs, errors.New("Mandrill API Key is empty."))
			return nil
		}

		md, err := gochimp.NewMandrill(apiKey)
		if err != nil {
			da.lastErrs = append(da.lastErrs, err)
			return nil
		}
		for _, o := range opts {
			o(md)
		}

		da.sendFunc = func(from string, to []string, msg io.WriterTo) error {

			// @todo figure out if "to" contains To, CC and BCC addresses.

			addr, err := mail.ParseAddress(from)
			if err != nil {
				return log.Error("mail.daemon.Mandrill.ParseAddress", "err", err, "from", from, "to", to)
			}

			r := gochimp.Recipient{
				Name:  addr.Name,
				Email: addr.Address,
			}

			var buf bytes.Buffer
			if _, err := msg.WriteTo(&buf); err != nil {
				return log.Error("mail.daemon.Mandrill.MessageWriteTo", "err", err, "from", from, "to", to, "msg", buf.String())
			}

			resp, err := md.MessageSendRaw(buf.String(), to, r, false)
			if err != nil {
				return log.Error("mail.daemon.Mandrill.MessageSendRaw", "err", err, "from", from, "to", to, "msg", buf.String())
			}
			if log.IsDebug() {
				log.Debug("mail.daemon.Mandrill.MessageSendRaw", "resp", resp, "from", from, "to", to, "msg", buf.String())
			}
			// The last arg in MessageSendRaw means async in the Mandrill API:
			// Async: enable a background sending mode that is optimized for bulk sending.
			// In async mode, messages/send will immediately return a status of "queued"
			// for every recipient. To handle rejections when sending in async mode, set
			// up a webhook for the 'reject' event. Defaults to false for messages with
			// no more than 10 recipients; messages with more than 10 recipients are
			// always sent asynchronously, regardless of the value of async.
			return nil
		}
		da.dialer = nil

		return nil
	}
}
Beispiel #2
0
func (dm *Daemon) getHost() string {
	h := dm.config.GetString(config.Path(PathSmtpHost), config.ScopeStore(dm.scopeID))
	if h == "" {
		h = defaultHost
	}
	return h
}
Beispiel #3
0
// ConfigString tries to get a value from the scopeStore if empty
// falls back to default global scope.
// If using etcd or consul maybe this can lead to round trip times because of network access.
func (s *Store) ConfigString(path ...string) string {
	val := s.cr.GetString(config.ScopeStore(s.StoreID()), config.Path(path...)) // TODO(cs) check for not bubbeling
	if val == "" {
		val = s.cr.GetString(config.Path(path...))
	}
	return val
}
Beispiel #4
0
func (dm *Daemon) getPort() int {
	p := dm.config.GetInt(config.Path(PathSmtpPort), config.ScopeStore(dm.scopeID))
	if p < 1 {
		p = defaultPort
	}
	return p
}
Beispiel #5
0
func (u *uniqueID) getHost() string {
	h := u.config.GetString(config.Path(PathSmtpHost), config.ScopeStore(u.scopeID))
	if h == "" {
		h = defaultHost
	}
	return h
}
Beispiel #6
0
// ConfigString tries to get a value from the scopeStore if empty
// falls back to default global scope.
// If using etcd or consul maybe this can lead to round trip times because of network access.
func (s *Store) ConfigString(path ...string) string {
	val := s.cr.GetString(config.ScopeStore(s), config.Path(path...))
	if val == "" {
		val = s.cr.GetString(config.Path(path...))
	}
	return val
}
Beispiel #7
0
func (c *emailConfig) getHost(s config.ScopeIDer) string {
	h := c.Config.GetString(config.Path(PathSmtpHost), config.ScopeStore(s))
	if h == "" {
		h = defaultHost
	}
	return h
}
Beispiel #8
0
func (c *emailConfig) getPort(s config.ScopeIDer) int {
	p := c.Config.GetInt(config.Path(PathSmtpPort), config.ScopeStore(s))
	if p < 1 {
		p = defaultPort
	}
	return p
}
Beispiel #9
0
func (u *uniqueID) getPort() int {
	p := u.config.GetInt(config.Path(PathSmtpPort), config.ScopeStore(u.scopeID))
	if p < 1 {
		p = defaultPort
	}
	return p
}
Beispiel #10
0
func TestPubSubEvict(t *testing.T) {
	defer debugLogBuf.Reset()

	levelCall := new(levelCalls)

	var pErr = errors.New("WTF Eviction? Panic!")
	s := config.NewService()
	subID, err := s.Subscribe("x/y", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Contains(t, path, "x/y")
			// this function gets called 3 times
			levelCall.Lock()
			levelCall.level2Calls++
			levelCall.Unlock()
			return nil
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID)

	subID, err = s.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			levelCall.Lock()
			levelCall.level3Calls++
			levelCall.Unlock()
			// this function gets called 1 times and then gets removed
			panic(pErr)
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 2, subID)

	assert.NoError(t, s.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123)))
	assert.NoError(t, s.Write(config.Value(321), config.Path("x/y/a"), config.ScopeStore(123)))
	assert.NoError(t, s.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123)))

	assert.NoError(t, s.Close())

	assert.Contains(t, debugLogBuf.String(), "config.pubSub.publish.recover.err err: WTF Eviction? Panic!")

	levelCall.Lock()
	assert.Equal(t, 3, levelCall.level2Calls)
	assert.Equal(t, 1, levelCall.level3Calls)
	levelCall.Unlock()
	assert.EqualError(t, s.Close(), config.ErrPublisherClosed.Error())
}
Beispiel #11
0
func (sca *SourceCurrencyAll) Options() config.ValueLabelSlice {
	// Magento\Framework\Locale\Resolver
	// grep locale from general/locale/code scope::store for the current store ID
	// the store locale greps the currencies from http://php.net/manual/en/class.resourcebundle.php
	// in the correct language
	storeLocale := sca.mc.ConfigReader.GetString(config.Path(PathDefaultLocale), config.ScopeStore(sca.mc.Scope))

	fmt.Printf("\nstoreLocale: %s\n", storeLocale)

	return nil
}
Beispiel #12
0
func TestPubSubEvict(t *testing.T) {
	defer errLogBuf.Reset()

	var level2Calls int
	var level3Calls int

	var pErr = errors.New("WTF Eviction? Panic!")
	m := config.NewManager()
	subID, err := m.Subscribe("x/y", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Contains(t, path, "x/y")
			// this function gets called 3 times
			level2Calls++
			return nil
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID)

	subID, err = m.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			level3Calls++
			// this function gets called 1 times and then gets removed
			panic(pErr)
			return nil
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 2, subID)

	m.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123), config.NoBubble())
	m.Write(config.Value(321), config.Path("x/y/a"), config.ScopeStore(123), config.NoBubble())
	m.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123), config.NoBubble())

	time.Sleep(time.Millisecond * 20) // wait for goroutine ...

	assert.Contains(t, errLogBuf.String(), "testErr: stdLib.go:228: config.pubSub.publish.recover.err err: WTF Eviction? Panic!")

	assert.Equal(t, 3, level2Calls)
	assert.Equal(t, 1, level3Calls)
}
Beispiel #13
0
func (sca *SourceCurrencyAll) Options() valuelabel.Slice {
	// Magento\Framework\Locale\Resolver
	// 1. get all allowed currencies from the config
	// 2. get slice of currency code and currency name and filter out all not-allowed currencies
	// grep locale from general/locale/code scope::store for the current store ID
	// the store locale greps the currencies from http://php.net/manual/en/class.resourcebundle.php
	// in the correct language
	storeLocale, err := sca.mc.ConfigReader.GetString(config.Path(PathDefaultLocale), config.ScopeStore(sca.mc.ScopeStore.StoreID()))

	fmt.Printf("\nstoreLocale: %s\n Err %s\n", storeLocale, err)

	return nil
}
Beispiel #14
0
func TestPubSubPanicSimple(t *testing.T) {
	defer debugLogBuf.Reset()
	testPath := "x/y/z"

	s := config.NewService()
	subID, err := s.Subscribe(testPath, &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			panic("Don't panic!")
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID, "The very first subscription ID should be 1")
	assert.NoError(t, s.Write(config.Value(321), config.Path(testPath), config.ScopeStore(123)))
	assert.NoError(t, s.Close())
	assert.Contains(t, debugLogBuf.String(), `config.pubSub.publish.recover.r recover: "Don't panic!"`)
}
Beispiel #15
0
func TestPubSubUnsubscribe(t *testing.T) {
	defer errLogBuf.Reset()

	var pErr = errors.New("WTF? Panic!")
	m := config.NewManager()
	subID, err := m.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			panic(pErr)
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID, "The very first subscription ID should be 1")
	assert.NoError(t, m.Unsubscribe(subID))
	assert.NoError(t, m.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123)))
	time.Sleep(time.Millisecond) // wait for goroutine ...
	assert.Contains(t, errLogBuf.String(), `config.Manager.Write path: "stores/123/x/y/z" val: 321`)
}
Beispiel #16
0
func TestPubSubPanic(t *testing.T) {
	defer errLogBuf.Reset()
	testPath := "x/y/z"

	m := config.NewManager()
	subID, err := m.Subscribe(testPath, &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			panic("Don't panic!")
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID, "The very first subscription ID should be 1")
	assert.NoError(t, m.Write(config.Value(321), config.Path(testPath), config.ScopeStore(123)))
	assert.NoError(t, m.Close())
	time.Sleep(time.Millisecond * 10) // wait for goroutine to close
	assert.Contains(t, errLogBuf.String(), `config.pubSub.publish.recover.r recover: "Don't panic!"`)
}
Beispiel #17
0
func TestPubSubPanicError(t *testing.T) {
	defer errLogBuf.Reset()
	testPath := "™/ö/º"

	var pErr = errors.New("OMG! Panic!")
	m := config.NewManager()
	subID, err := m.Subscribe(testPath, &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			panic(pErr)
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID, "The very first subscription ID should be 1")
	assert.NoError(t, m.Write(config.Value(321), config.Path(testPath), config.ScopeStore(123)))
	// not closing channel to let the Goroutine around egging aka. herumeiern.
	time.Sleep(time.Millisecond * 10) // wait for goroutine ...
	assert.Contains(t, errLogBuf.String(), `config.pubSub.publish.recover.err err: OMG! Panic!`)
}
Beispiel #18
0
func TestPubSubUnsubscribe(t *testing.T) {
	defer debugLogBuf.Reset()

	var pErr = errors.New("WTF? Panic!")
	s := config.NewService()
	subID, err := s.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			panic(pErr)
		},
	})
	assert.NoError(t, err)
	assert.Equal(t, 1, subID, "The very first subscription ID should be 1")
	assert.NoError(t, s.Unsubscribe(subID))
	assert.NoError(t, s.Write(config.Value(321), config.Path("x/y/z"), config.ScopeStore(123)))
	assert.NoError(t, s.Close())
	assert.Contains(t, debugLogBuf.String(), `config.Service.Write path: "stores/123/x/y/z" val: 321`)

}
Beispiel #19
0
func TestPubSubPanicMultiple(t *testing.T) {
	defer errLogBuf.Reset()
	m := config.NewManager()

	subID, err := m.Subscribe("x", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("One: Don't panic!")
			return nil
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	subID, err = m.Subscribe("x/y", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("Two: Don't panic!")
			return nil
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	subID, err = m.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("Three: Don't panic!")
			return nil
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	m.Write(config.Value(789), config.Path("x/y/z"), config.ScopeStore(987), config.NoBubble())
	assert.NoError(t, m.Close())
	time.Sleep(time.Millisecond * 30) // wait for goroutine to close
	assert.Contains(t, errLogBuf.String(), `testErr: stdLib.go:228: config.pubSub.publish.recover.r recover: "One: Don't panic!`)
	assert.Contains(t, errLogBuf.String(), `testErr: stdLib.go:228: config.pubSub.publish.recover.r recover: "Two: Don't panic!"`)
	assert.Contains(t, errLogBuf.String(), `testErr: stdLib.go:228: config.pubSub.publish.recover.r recover: "Three: Don't panic!"`)
}
Beispiel #20
0
func TestPubSubPanicMultiple(t *testing.T) {
	defer debugLogBuf.Reset()
	s := config.NewService()

	subID, err := s.Subscribe("x", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("One: Don't panic!")
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	subID, err = s.Subscribe("x/y", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("Two: Don't panic!")
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	subID, err = s.Subscribe("x/y/z", &testSubscriber{
		f: func(path string, sg scope.Scope, id int64) error {
			assert.Equal(t, "x/y/z", path)
			panic("Three: Don't panic!")
		},
	})
	assert.NoError(t, err)
	assert.True(t, subID > 0)

	assert.NoError(t, s.Write(config.Value(789), config.Path("x/y/z"), config.ScopeStore(987)))
	assert.NoError(t, s.Close())

	assert.Contains(t, debugLogBuf.String(), `config.pubSub.publish.recover.r recover: "One: Don't panic!`)
	assert.Contains(t, debugLogBuf.String(), `config.pubSub.publish.recover.r recover: "Two: Don't panic!"`)
	assert.Contains(t, debugLogBuf.String(), `config.pubSub.publish.recover.r recover: "Three: Don't panic!"`)
}
Beispiel #21
0
func (c *emailConfig) getUsername(s config.ScopeIDer) string {
	return c.Config.GetString(config.Path(PathSmtpUsername), config.ScopeStore(s))
}
Beispiel #22
0
func (c *emailConfig) getPassword(s config.ScopeIDer) string {
	return c.Config.GetString(config.Path(PathSmtpPassword), config.ScopeStore(s))
}
Beispiel #23
0
// IsOffline checks if SMTP sending for the current scope ID has been deactivated.
// If disabled the output will be logged.
func (dm *Daemon) IsOffline() bool {
	if nil == dm.Config {
		return true
	}
	return dm.Config.GetBool(config.Path(PathSmtpDisable), config.ScopeStore(dm.ScopeID))
}
Beispiel #24
0
// DefaultCountry returns the country code. Store argument is optional.
func DefaultCountry(cr config.Reader, r config.ScopeIDer) string {
	return cr.GetString(config.Path(PathDefaultCountry), config.ScopeStore(r))
}
Beispiel #25
0
func (u *uniqueID) getUsername() string {
	return u.config.GetString(config.Path(PathSmtpUsername), config.ScopeStore(u.scopeID))
}
Beispiel #26
0
// IsSingleStoreMode check if Single-Store mode is enabled in configuration and from Store count < 3.
// This flag only shows that admin does not want to show certain UI components at backend (like store switchers etc)
// if Magento has only one store view but it does not check the store view collection.
func (sm *Manager) IsSingleStoreMode() bool {
	return sm.HasSingleStore() && sm.cr.GetBool(config.Path(PathSingleStoreModeEnabled), config.ScopeStore(sm.appStore))
}
Beispiel #27
0
func (dm *Daemon) getPassword() string {
	// @todo decryption of the encrpted stored password? or extend config.Reader API?
	return dm.config.GetString(config.Path(PathSmtpPassword), config.ScopeStore(dm.scopeID))
}
Beispiel #28
0
// ShowNonRequiredState
func ShowNonRequiredState(cr config.Reader, r scope.StoreIDer) bool {
	return cr.GetBool(config.ScopeStore(r.StoreID()), config.Path(PathDisplayAllStates))
}
Beispiel #29
0
func (dm *Daemon) getUsername() string {
	return dm.config.GetString(config.Path(PathSmtpUsername), config.ScopeStore(dm.scopeID))
}