func (p *Provider) RestartRESTService() {
	go func() {
		p.restartRESTService()
	}()
}
RestartRESTService restarts the REST server
package sidetreesvc
import (
	"fmt"
	"sync"
	"github.com/hyperledger/fabric/common/flogging"
	ledgerconfig "github.com/trustbloc/fabric-peer-ext/pkg/config/ledgerconfig/config"
	"github.com/trustbloc/sidetree-core-go/pkg/restapi/common"
	"github.com/trustbloc/sidetree-fabric/pkg/config"
	ctxcommon "github.com/trustbloc/sidetree-fabric/pkg/context/common"
	"github.com/trustbloc/sidetree-fabric/pkg/observer"
	"github.com/trustbloc/sidetree-fabric/pkg/peer/discovery"
)
var logger = flogging.MustGetLogger("sidetree_peer")
type configServiceProvider interface {
	ForChannel(channelID string) ledgerconfig.Service
}
type peerConfig interface {
	PeerID() string
	PeerAddress() string
	MSPID() string
}
type restConfig interface {
	SidetreeListenURL() (string, error)
	SidetreeListenPort() int
	SidetreeTLSCertificate() string
	SidetreeTLSKey() string
	SidetreeAPIToken(name string) string
}
type sidetreeConfigProvider interface {
	ForChannel(channelID string) config.SidetreeService
}
type discoveryProvider interface {
	UpdateLocalServicesForChannel(channelID string, services []discovery.Service)
	ServicesForChannel(channelID string) []discovery.Service
}
type providers struct {
	*ContextProviders
	PeerConfig        peerConfig
	RESTConfig        restConfig
	ConfigProvider    configServiceProvider
	ObserverProviders *observer.ClientProviders
	BlockPublisher    ctxcommon.BlockPublisherProvider
	DiscoveryProvider discoveryProvider
}
type Provider struct {
	*providers
	sidetreeConfigProvider sidetreeConfigProvider
	restService            *restService
	chanControllers        map[string]*channelController
	mutex                  sync.RWMutex
}
func NewProvider(providers *providers, sidetreeConfigProvider sidetreeConfigProvider) *Provider {
	logger.Info("Creating Sidetree services provider")
	return &Provider{
		providers:              providers,
		sidetreeConfigProvider: sidetreeConfigProvider,
		chanControllers:        make(map[string]*channelController),
	}
}
func (p *Provider) ChannelJoined(channelID string) {
	logger.Infof("[%s] Joined channel.", channelID)
	sidetreeCfgService := p.sidetreeConfigProvider.ForChannel(channelID)
	ctrl := newChannelController(channelID, p.providers, sidetreeCfgService, p)
	go func() {
		if err := ctrl.load(); err != nil {
			logger.Warnf("[%s] Error loading Sidetree service channelController: %s. The configuration may not yet be loaded. Once the configuration is loaded, the Sidetree service channelController will be started.", channelID, err)
		}
	}()
	p.mutex.Lock()
	defer p.mutex.Unlock()
	p.chanControllers[channelID] = ctrl
}
func (p *Provider) ProtocolClientProviderForChannel(channelID string) (ctxcommon.ProtocolClientProvider, error) {
	p.mutex.RLock()
	defer p.mutex.RUnlock()
	ctrl, ok := p.chanControllers[channelID]
	if !ok {
		return nil, fmt.Errorf("protocol client provider not found for channel [%s]", channelID)
	}
	return ctrl, nil
}
func (p *Provider) Close() {
	logger.Infof("Closing Sidetree resources ...")
	p.mutex.Lock()
	defer p.mutex.Unlock()
	if p.restService != nil {
		p.restService.Stop()
		p.restService = nil
	}
	for _, service := range p.chanControllers {
		service.Close()
	}
	logger.Infof("... successfully closed Sidetree resources.")
}