// DialApplicationClientProtocolService connects to an ApplicationClientProtocolService at the specified network address.
func DialApplicationClientProtocolService(conf yarn_conf.YarnConfiguration) (ApplicationClientProtocolService, error) {
	clientId, _ := uuid.NewV4()
	ugi, _ := gohadoop.CreateSimpleUGIProto()
	serverAddress, _ := conf.GetRMAddress()
	c := &hadoop_ipc_client.Client{ClientId: clientId, Ugi: ugi, ServerAddress: serverAddress}
	return &ApplicationClientProtocolServiceClient{c}, nil
}
func writeConnectionContext(c *Client, conn *connection, connectionId *connection_id, authProtocol gohadoop.AuthProtocol) error {
	// Create hadoop_common.IpcConnectionContextProto
	ugi, _ := gohadoop.CreateSimpleUGIProto()
	ipcCtxProto := hadoop_common.IpcConnectionContextProto{UserInfo: ugi, Protocol: &connectionId.protocol}

	// Create RpcRequestHeaderProto
	var callId int32 = -3
	var clientId [16]byte = [16]byte(*c.ClientId)

	/*if (authProtocol == gohadoop.AUTH_PROTOCOL_SASL) {
	  callId = SASL_RPC_CALL_ID
	}*/

	rpcReqHeaderProto := hadoop_common.RpcRequestHeaderProto{RpcKind: &gohadoop.RPC_PROTOCOL_BUFFFER, RpcOp: &gohadoop.RPC_FINAL_PACKET, CallId: &callId, ClientId: clientId[0:16], RetryCount: &gohadoop.RPC_DEFAULT_RETRY_COUNT}

	rpcReqHeaderProtoBytes, err := proto.Marshal(&rpcReqHeaderProto)
	if err != nil {
		log.Fatal("proto.Marshal(&rpcReqHeaderProto)", err)
		return err
	}

	ipcCtxProtoBytes, _ := proto.Marshal(&ipcCtxProto)
	if err != nil {
		log.Fatal("proto.Marshal(&ipcCtxProto)", err)
		return err
	}

	totalLength := len(rpcReqHeaderProtoBytes) + sizeVarint(len(rpcReqHeaderProtoBytes)) + len(ipcCtxProtoBytes) + sizeVarint(len(ipcCtxProtoBytes))
	var tLen int32 = int32(totalLength)
	totalLengthBytes, err := gohadoop.ConvertFixedToBytes(tLen)

	if err != nil {
		log.Fatal("ConvertFixedToBytes(totalLength)", err)
		return err
	} else if _, err := conn.con.Write(totalLengthBytes); err != nil {
		log.Fatal("conn.con.Write(totalLengthBytes)", err)
		return err
	}

	if err := writeDelimitedBytes(conn, rpcReqHeaderProtoBytes); err != nil {
		log.Fatal("writeDelimitedBytes(conn, rpcReqHeaderProtoBytes)", err)
		return err
	}
	if err := writeDelimitedBytes(conn, ipcCtxProtoBytes); err != nil {
		log.Fatal("writeDelimitedBytes(conn, ipcCtxProtoBytes)", err)
		return err
	}

	return nil
}
func main() {
	var err error

	clientId, _ := uuid.NewV4()
	ugi, _ := gohadoop.CreateSimpleUGIProto()
	c := &ipc.Client{ClientId: clientId, Ugi: ugi, ServerAddress: "0.0.0.0:28081"}
	var clientProtocolVersion uint64 = 1
	var methodName string
	var protocolName string

	// ApplicationClientProtocol.getApplications
	methodName = "getApplications"
	protocolName = "org.apache.hadoop.yarn.api.ApplicationClientProtocolPB"
	getAppsRpcProto := hadoop_common.RequestHeaderProto{MethodName: &methodName, DeclaringClassProtocolName: &protocolName, ClientProtocolVersion: &clientProtocolVersion}
	applicationStates := []hadoop_yarn.YarnApplicationStateProto{hadoop_yarn.YarnApplicationStateProto_ACCEPTED, hadoop_yarn.YarnApplicationStateProto_RUNNING, hadoop_yarn.YarnApplicationStateProto_SUBMITTED}
	getAppsReqProto := hadoop_yarn.GetApplicationsRequestProto{ApplicationStates: applicationStates}
	getAppsResProto := hadoop_yarn.GetApplicationsResponseProto{}
	log.Println("Calling rpc method: ", methodName)
	err = c.Call(&getAppsRpcProto, &getAppsReqProto, &getAppsResProto)
	if err != nil {
		log.Fatal("Client.call failed", err)
	}
	log.Println("Returned response: ", getAppsResProto)

	// ApplicationClientProtocol.getNewApplication
	methodName = "getNewApplication"
	protocolName = "org.apache.hadoop.yarn.api.ApplicationClientProtocolPB"
	getNewAppRpcProto := hadoop_common.RequestHeaderProto{MethodName: &methodName, DeclaringClassProtocolName: &protocolName, ClientProtocolVersion: &clientProtocolVersion}
	getNewAppReqProto := hadoop_yarn.GetNewApplicationRequestProto{}
	getNewAppResProto := hadoop_yarn.GetNewApplicationResponseProto{}
	log.Println("Calling rpc method: ", methodName)
	err = c.Call(&getNewAppRpcProto, &getNewAppReqProto, &getNewAppResProto)
	if err != nil {
		log.Fatal("Client.call failed", err)
	}
	log.Println("Returned response: ", getNewAppResProto)
}
// DialContainerManagementProtocolService connects to an ContainerManagementProtocolService at the specified network address.
func DialContainerManagementProtocolService(host string, port int) (ContainerManagementProtocolService, error) {
  clientId, _ := uuid.NewV4()
  ugi, _ := gohadoop.CreateSimpleUGIProto()
  c := &hadoop_ipc_client.Client{ClientId: clientId, Ugi: ugi, ServerAddress: net.JoinHostPort(host, strconv.Itoa(port))}
	return &ContainerManagementProtocolServiceClient{c}, nil
}