<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package apiserver

import (
	"errors"
	"time"

	"launchpad.net/tomb"

	"launchpad.net/juju-core/rpc"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/apiserver/agent"
	"launchpad.net/juju-core/state/apiserver/charmrevisionupdater"
	"launchpad.net/juju-core/state/apiserver/client"
	"launchpad.net/juju-core/state/apiserver/common"
	"launchpad.net/juju-core/state/apiserver/deployer"
	"launchpad.net/juju-core/state/apiserver/firewaller"
	"launchpad.net/juju-core/state/apiserver/keymanager"
	"launchpad.net/juju-core/state/apiserver/keyupdater"
	loggerapi "launchpad.net/juju-core/state/apiserver/logger"
	"launchpad.net/juju-core/state/apiserver/machine"
	"launchpad.net/juju-core/state/apiserver/provisioner"
	"launchpad.net/juju-core/state/apiserver/uniter"
	"launchpad.net/juju-core/state/apiserver/upgrader"
	"launchpad.net/juju-core/state/multiwatcher"
)

type clientAPI struct{ *client.API }

type taggedAuthenticator interface {
	state.Entity
	state.Authenticator
}

// maxPingInterval defines the timeframe until the ping
// timeout closes the monitored connection.
// TODO(mue): Idea by Roger: Move to API (e.g. params) so
// that the pinging there may depend on the interval.
var maxPingInterval = 3 * time.Minute

// srvRoot represents a single client's connection to the state
// after it has logged in.
type srvRoot struct {
	clientAPI
	srv         *Server
	rpcConn     *rpc.Conn
	resources   *common.Resources
	pingTimeout *pingTimeout

	entity taggedAuthenticator
}

// newSrvRoot creates the client's connection representation
// and starts a ping timeout for the monitoring of this
// connection.
func newSrvRoot(root *initialRoot, entity taggedAuthenticator) *srvRoot {
	r := &srvRoot{
		srv:       root.srv,
		rpcConn:   root.rpcConn,
		resources: common.NewResources(),
		entity:    entity,
	}
	r.clientAPI.API = client.NewAPI(r.srv.state, r.resources, r, r.srv.dataDir)
	return r
}

// Kill implements rpc.Killer.  It cleans up any resources that need
// cleaning up to ensure that all outstanding requests return.
func (r *srvRoot) Kill() {
	r.resources.StopAll()
	if r.pingTimeout != nil {
		r.pingTimeout.stop()
	}
}

// requireAgent checks whether the current client is an agent and hence
// may access the agent APIs.  We filter out non-agents when calling one
// of the accessor functions (Machine, Unit, etc) which avoids us making
// the check in every single request method.
func (r *srvRoot) requireAgent() error {
	if !isAgent(r.entity) {
		return common.ErrPerm
	}
	return nil
}

// requireClient returns an error unless the current
// client is a juju client user.
func (r *srvRoot) requireClient() error {
	if isAgent(r.entity) {
		return common.ErrPerm
	}
	return nil
}

// KeyManager returns an object that provides access to the KeyManager API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) KeyManager(id string) (*keymanager.KeyManagerAPI, error) {
	if id != "" {
		return nil, common.ErrBadId
	}
	return keymanager.NewKeyManagerAPI(r.srv.state, r.resources, r)
}

// Machiner returns an object that provides access to the Machiner API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) Machiner(id string) (*machine.MachinerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return machine.NewMachinerAPI(r.srv.state, r.resources, r)
}

// Provisioner returns an object that provides access to the
// Provisioner API facade. The id argument is reserved for future use
// and currently needs to be empty.
func (r *srvRoot) Provisioner(id string) (*provisioner.ProvisionerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return provisioner.NewProvisionerAPI(r.srv.state, r.resources, r)
}

// Uniter returns an object that provides access to the Uniter API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) Uniter(id string) (*uniter.UniterAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return uniter.NewUniterAPI(r.srv.state, r.resources, r)
}

// Firewaller returns an object that provides access to the Firewaller
// API facade. The id argument is reserved for future use and
// currently needs to be empty.
func (r *srvRoot) Firewaller(id string) (*firewaller.FirewallerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return firewaller.NewFirewallerAPI(r.srv.state, r.resources, r)
}

// Agent returns an object that provides access to the
// agent API.  The id argument is reserved for future use and must currently
// be empty.
func (r *srvRoot) Agent(id string) (*agent.API, error) {
	if id != "" {
		return nil, common.ErrBadId
	}
	return agent.NewAPI(r.srv.state, r)
}

// Deployer returns an object that provides access to the Deployer API facade.
// The id argument is reserved for future use and must be empty.
func (r *srvRoot) Deployer(id string) (*deployer.DeployerAPI, error) {
	if id != "" {
		// TODO(dimitern): There is no direct test for this
		return nil, common.ErrBadId
	}
	return deployer.NewDeployerAPI(r.srv.state, r.resources, r)
}

// Logger returns an object that provides access to the Logger API facade.
// The id argument is reserved for future use and must be empty.
func (r *srvRoot) Logger(id string) (*loggerapi.LoggerAPI, error) {
	if id != "" {<commit_msg>Hook up the environment server end-point.<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package apiserver

import (
	"errors"
	"time"

	"launchpad.net/tomb"

	"launchpad.net/juju-core/rpc"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/apiserver/agent"
	"launchpad.net/juju-core/state/apiserver/charmrevisionupdater"
	"launchpad.net/juju-core/state/apiserver/client"
	"launchpad.net/juju-core/state/apiserver/common"
	"launchpad.net/juju-core/state/apiserver/deployer"
	"launchpad.net/juju-core/state/apiserver/environment"
	"launchpad.net/juju-core/state/apiserver/firewaller"
	"launchpad.net/juju-core/state/apiserver/keymanager"
	"launchpad.net/juju-core/state/apiserver/keyupdater"
	loggerapi "launchpad.net/juju-core/state/apiserver/logger"
	"launchpad.net/juju-core/state/apiserver/machine"
	"launchpad.net/juju-core/state/apiserver/provisioner"
	"launchpad.net/juju-core/state/apiserver/uniter"
	"launchpad.net/juju-core/state/apiserver/upgrader"
	"launchpad.net/juju-core/state/multiwatcher"
)

type clientAPI struct{ *client.API }

type taggedAuthenticator interface {
	state.Entity
	state.Authenticator
}

// maxPingInterval defines the timeframe until the ping
// timeout closes the monitored connection.
// TODO(mue): Idea by Roger: Move to API (e.g. params) so
// that the pinging there may depend on the interval.
var maxPingInterval = 3 * time.Minute

// srvRoot represents a single client's connection to the state
// after it has logged in.
type srvRoot struct {
	clientAPI
	srv         *Server
	rpcConn     *rpc.Conn
	resources   *common.Resources
	pingTimeout *pingTimeout

	entity taggedAuthenticator
}

// newSrvRoot creates the client's connection representation
// and starts a ping timeout for the monitoring of this
// connection.
func newSrvRoot(root *initialRoot, entity taggedAuthenticator) *srvRoot {
	r := &srvRoot{
		srv:       root.srv,
		rpcConn:   root.rpcConn,
		resources: common.NewResources(),
		entity:    entity,
	}
	r.clientAPI.API = client.NewAPI(r.srv.state, r.resources, r, r.srv.dataDir)
	return r
}

// Kill implements rpc.Killer.  It cleans up any resources that need
// cleaning up to ensure that all outstanding requests return.
func (r *srvRoot) Kill() {
	r.resources.StopAll()
	if r.pingTimeout != nil {
		r.pingTimeout.stop()
	}
}

// requireAgent checks whether the current client is an agent and hence
// may access the agent APIs.  We filter out non-agents when calling one
// of the accessor functions (Machine, Unit, etc) which avoids us making
// the check in every single request method.
func (r *srvRoot) requireAgent() error {
	if !isAgent(r.entity) {
		return common.ErrPerm
	}
	return nil
}

// requireClient returns an error unless the current
// client is a juju client user.
func (r *srvRoot) requireClient() error {
	if isAgent(r.entity) {
		return common.ErrPerm
	}
	return nil
}

// KeyManager returns an object that provides access to the KeyManager API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) KeyManager(id string) (*keymanager.KeyManagerAPI, error) {
	if id != "" {
		return nil, common.ErrBadId
	}
	return keymanager.NewKeyManagerAPI(r.srv.state, r.resources, r)
}

// Machiner returns an object that provides access to the Machiner API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) Machiner(id string) (*machine.MachinerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return machine.NewMachinerAPI(r.srv.state, r.resources, r)
}

// Provisioner returns an object that provides access to the
// Provisioner API facade. The id argument is reserved for future use
// and currently needs to be empty.
func (r *srvRoot) Provisioner(id string) (*provisioner.ProvisionerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return provisioner.NewProvisionerAPI(r.srv.state, r.resources, r)
}

// Uniter returns an object that provides access to the Uniter API
// facade. The id argument is reserved for future use and currently
// needs to be empty.
func (r *srvRoot) Uniter(id string) (*uniter.UniterAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return uniter.NewUniterAPI(r.srv.state, r.resources, r)
}

// Firewaller returns an object that provides access to the Firewaller
// API facade. The id argument is reserved for future use and
// currently needs to be empty.
func (r *srvRoot) Firewaller(id string) (*firewaller.FirewallerAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return firewaller.NewFirewallerAPI(r.srv.state, r.resources, r)
}

// Agent returns an object that provides access to the
// agent API.  The id argument is reserved for future use and must currently
// be empty.
func (r *srvRoot) Agent(id string) (*agent.API, error) {
	if id != "" {
		return nil, common.ErrBadId
	}
	return agent.NewAPI(r.srv.state, r)
}

// Deployer returns an object that provides access to the Deployer API facade.
// The id argument is reserved for future use and must be empty.
func (r *srvRoot) Deployer(id string) (*deployer.DeployerAPI, error) {
	if id != "" {
		// TODO(dimitern): There is no direct test for this
		return nil, common.ErrBadId
	}
	return deployer.NewDeployerAPI(r.srv.state, r.resources, r)
}

// Environment returns an object that provides access to the Environment API
// facade. The id argument is reserved for future use and currently needs to
// be empty.
func (r *srvRoot) Environment(id string) (*environment.EnvironmentAPI, error) {
	if id != "" {
		// Safeguard id for possible future use.
		return nil, common.ErrBadId
	}
	return environment.NewEnvironmentAPI(r.srv.state, r.resources, r)
}

// Logger returns an object that provides access to the Logger API facade.
// The id argument is reserved for future use and must be empty.
func (r *srvRoot) Logger(id string) (*loggerapi.LoggerAPI, error) {
	if id != "" {
{'fraction_non_alphanumeric': 0.10467969873910468, 'fraction_numerical': 0.0010154861640010156, 'mean_word_length': 3.881453944650971, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7624559', 'n_tokens_mistral': 4038, 'n_tokens_neox': 3839, 'n_words': 1268}