func NewFromConfig(opts *clientconfig.NifiConfig) (NifiClient, error) {
	var client NifiClient
	var err error
	if opts == nil {
		return nil, errorfactory.New(errorfactory.NilClientConfig{}, errors.New("The NiFi client config is nil"), "The NiFi client config is nil")
	}
	client = New(opts)
	err = client.Build()
	if err != nil {
		return nil, err
	}
	return client, nil
}
NewFromConfig is a convenient wrapper around New() and ClusterConfig()
package nificlient
import (
	"context"
	"emperror.dev/errors"
	"fmt"
	"github.com/Orange-OpenSource/nifikop/pkg/util/clientconfig"
	"net/http"
	"net/url"
	ctrl "sigs.k8s.io/controller-runtime"
	"time"
	"github.com/Orange-OpenSource/nifikop/pkg/errorfactory"
	nigoapi "github.com/erdrix/nigoapi/pkg/nifi"
)
var log = ctrl.Log.WithName("nifi_client")
const (
	PRIMARY_NODE        = "Primary Node"
	CLUSTER_COORDINATOR = "Cluster Coordinator"
	CONNECTING_STATUS = "CONNECTING"
	CONNECTED_STATUS = "CONNECTED"
	DISCONNECTING_STATUS = "DISCONNECTING"
	DISCONNECTED_STATUS = "DISCONNECTED"
	OFFLOADING_STATUS = "OFFLOADING"
	OFFLOADED_STATUS = "OFFLOADED"
	REMOVING_STATUS = "REMOVING"
	REMOVED_STATUS = "REMOVED"
)
type NifiClient interface {
	CreateAccessTokenUsingBasicAuth(username, password string, nodeId int32) (*string, error)
	DescribeCluster() (*nigoapi.ClusterEntity, error)
	DescribeClusterFromNodeId(nodeId int32) (*nigoapi.ClusterEntity, error)
	DisconnectClusterNode(nId int32) (*nigoapi.NodeEntity, error)
	ConnectClusterNode(nId int32) (*nigoapi.NodeEntity, error)
	OffloadClusterNode(nId int32) (*nigoapi.NodeEntity, error)
	RemoveClusterNode(nId int32) error
	GetClusterNode(nId int32) (*nigoapi.NodeEntity, error)
	RemoveClusterNodeFromClusterNodeId(nId string) error
	GetRegistryClient(id string) (*nigoapi.RegistryClientEntity, error)
	CreateRegistryClient(entity nigoapi.RegistryClientEntity) (*nigoapi.RegistryClientEntity, error)
	UpdateRegistryClient(entity nigoapi.RegistryClientEntity) (*nigoapi.RegistryClientEntity, error)
	RemoveRegistryClient(entity nigoapi.RegistryClientEntity) error
	GetFlow(id string) (*nigoapi.ProcessGroupFlowEntity, error)
	UpdateFlowControllerServices(entity nigoapi.ActivateControllerServicesEntity) (*nigoapi.ActivateControllerServicesEntity, error)
	UpdateFlowProcessGroup(entity nigoapi.ScheduleComponentsEntity) (*nigoapi.ScheduleComponentsEntity, error)
	GetFlowControllerServices(id string) (*nigoapi.ControllerServicesEntity, error)
	GetDropRequest(connectionId, id string) (*nigoapi.DropRequestEntity, error)
	CreateDropRequest(connectionId string) (*nigoapi.DropRequestEntity, error)
	GetProcessGroup(id string) (*nigoapi.ProcessGroupEntity, error)
	CreateProcessGroup(entity nigoapi.ProcessGroupEntity, pgParentId string) (*nigoapi.ProcessGroupEntity, error)
	UpdateProcessGroup(entity nigoapi.ProcessGroupEntity) (*nigoapi.ProcessGroupEntity, error)
	RemoveProcessGroup(entity nigoapi.ProcessGroupEntity) error
	CreateVersionUpdateRequest(pgId string, entity nigoapi.VersionControlInformationEntity) (*nigoapi.VersionedFlowUpdateRequestEntity, error)
	GetVersionUpdateRequest(id string) (*nigoapi.VersionedFlowUpdateRequestEntity, error)
	CreateVersionRevertRequest(pgId string, entity nigoapi.VersionControlInformationEntity) (*nigoapi.VersionedFlowUpdateRequestEntity, error)
	GetVersionRevertRequest(id string) (*nigoapi.VersionedFlowUpdateRequestEntity, error)
	CreateSnippet(entity nigoapi.SnippetEntity) (*nigoapi.SnippetEntity, error)
	UpdateSnippet(entity nigoapi.SnippetEntity) (*nigoapi.SnippetEntity, error)
	UpdateProcessor(entity nigoapi.ProcessorEntity) (*nigoapi.ProcessorEntity, error)
	UpdateProcessorRunStatus(id string, entity nigoapi.ProcessorRunStatusEntity) (*nigoapi.ProcessorEntity, error)
	UpdateInputPortRunStatus(id string, entity nigoapi.PortRunStatusEntity) (*nigoapi.ProcessorEntity, error)
	GetParameterContext(id string) (*nigoapi.ParameterContextEntity, error)
	CreateParameterContext(entity nigoapi.ParameterContextEntity) (*nigoapi.ParameterContextEntity, error)
	RemoveParameterContext(entity nigoapi.ParameterContextEntity) error
	CreateParameterContextUpdateRequest(contextId string, entity nigoapi.ParameterContextEntity) (*nigoapi.ParameterContextUpdateRequestEntity, error)
	GetParameterContextUpdateRequest(contextId, id string) (*nigoapi.ParameterContextUpdateRequestEntity, error)
	GetUserGroups() ([]nigoapi.UserGroupEntity, error)
	GetUserGroup(id string) (*nigoapi.UserGroupEntity, error)
	CreateUserGroup(entity nigoapi.UserGroupEntity) (*nigoapi.UserGroupEntity, error)
	UpdateUserGroup(entity nigoapi.UserGroupEntity) (*nigoapi.UserGroupEntity, error)
	RemoveUserGroup(entity nigoapi.UserGroupEntity) error
	GetUsers() ([]nigoapi.UserEntity, error)
	GetUser(id string) (*nigoapi.UserEntity, error)
	CreateUser(entity nigoapi.UserEntity) (*nigoapi.UserEntity, error)
	UpdateUser(entity nigoapi.UserEntity) (*nigoapi.UserEntity, error)
	RemoveUser(entity nigoapi.UserEntity) error
	GetAccessPolicy(action, resource string) (*nigoapi.AccessPolicyEntity, error)
	CreateAccessPolicy(entity nigoapi.AccessPolicyEntity) (*nigoapi.AccessPolicyEntity, error)
	UpdateAccessPolicy(entity nigoapi.AccessPolicyEntity) (*nigoapi.AccessPolicyEntity, error)
	RemoveAccessPolicy(entity nigoapi.AccessPolicyEntity) error
	GetReportingTask(id string) (*nigoapi.ReportingTaskEntity, error)
	CreateReportingTask(entity nigoapi.ReportingTaskEntity) (*nigoapi.ReportingTaskEntity, error)
	UpdateReportingTask(entity nigoapi.ReportingTaskEntity) (*nigoapi.ReportingTaskEntity, error)
	UpdateRunStatusReportingTask(id string, entity nigoapi.ReportingTaskRunStatusEntity) (*nigoapi.ReportingTaskEntity, error)
	RemoveReportingTask(entity nigoapi.ReportingTaskEntity) error
	GetControllerConfig() (*nigoapi.ControllerConfigurationEntity, error)
	UpdateControllerConfig(entity nigoapi.ControllerConfigurationEntity) (*nigoapi.ControllerConfigurationEntity, error)
	Build() error
}
type nifiClient struct {
	NifiClient
	opts       *clientconfig.NifiConfig
	client     *nigoapi.APIClient
	nodeClient map[int32]*nigoapi.APIClient
	timeout    time.Duration
	nodes      []nigoapi.NodeDto
	newClient func(*nigoapi.Configuration) *nigoapi.APIClient
}
func New(opts *clientconfig.NifiConfig) NifiClient {
	nClient := &nifiClient{
		opts:    opts,
		timeout: time.Duration(opts.OperationTimeout) * time.Second,
	}
	nClient.newClient = nigoapi.NewAPIClient
	return nClient
}
func (n *nifiClient) Build() error {
	config := n.getNifiGoApiConfig()
	n.client = n.newClient(config)
	n.nodeClient = make(map[int32]*nigoapi.APIClient)
	for nodeId, _ := range n.opts.NodesURI {
		nodeConfig := n.getNiNodeGoApiConfig(nodeId)
		n.nodeClient[nodeId] = n.newClient(nodeConfig)
	}
	if !n.opts.SkipDescribeCluster {
		clusterEntity, err := n.DescribeCluster()
		if err != nil || clusterEntity == nil || clusterEntity.Cluster == nil {
			err = errorfactory.New(errorfactory.NodesUnreachable{}, err, fmt.Sprintf("could not connect to nifi nodes: %s", n.opts.NifiURI))
			return err
		}
		n.nodes = clusterEntity.Cluster.Nodes
	}
	return nil
}