예제 #1
0
func TestSession_CheckCorrectCompID(t *testing.T) {
	session := Session{}
	session.sessionID.TargetCompID = "TAR"
	session.sessionID.SenderCompID = "SND"

	var testCases = []struct {
		senderCompID *field.SenderCompIDField
		targetCompID *field.TargetCompIDField
		returnsError bool
		rejectReason int
	}{
		{returnsError: true, rejectReason: rejectReasonRequiredTagMissing},
		{senderCompID: field.NewSenderCompID("TAR"),
			returnsError: true,
			rejectReason: rejectReasonRequiredTagMissing},
		{senderCompID: field.NewSenderCompID("TAR"),
			targetCompID: field.NewTargetCompID("JCD"),
			returnsError: true,
			rejectReason: rejectReasonCompIDProblem},
		{senderCompID: field.NewSenderCompID("JCD"),
			targetCompID: field.NewTargetCompID("SND"),
			returnsError: true,
			rejectReason: rejectReasonCompIDProblem},
		{senderCompID: field.NewSenderCompID("TAR"),
			targetCompID: field.NewTargetCompID("SND"),
			returnsError: false},
	}

	for _, tc := range testCases {
		builder := getBuilder()

		if tc.senderCompID != nil {
			builder.Header().Set(tc.senderCompID)
		}

		if tc.targetCompID != nil {
			builder.Header().Set(tc.targetCompID)
		}

		msgBytes, _ := builder.Build()
		msg, _ := parseMessage(msgBytes)
		err := session.checkCompID(*msg)

		if err == nil {
			if tc.returnsError {
				t.Error("expected error")
			}

			return
		}

		if !tc.returnsError {
			t.Fatal("unexpected error", err)
		}

		if err.RejectReason() != tc.rejectReason {
			t.Errorf("expected %v got %v", tc.rejectReason, err.RejectReason())
		}
	}
}
예제 #2
0
func (s *Session) fillDefaultHeader(builder MessageBuilder) {
	builder.Header().Set(field.NewBeginString(s.sessionID.BeginString))
	builder.Header().Set(field.NewSenderCompID(s.sessionID.SenderCompID))
	builder.Header().Set(field.NewTargetCompID(s.sessionID.TargetCompID))

	s.insertSendingTime(builder.Header())
}
예제 #3
0
func queryTargetCompID() (*field.TargetCompIDField, error) {
	fmt.Println()
	fmt.Print("TargetCompID: ")

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()

	return field.NewTargetCompID(scanner.Text()), scanner.Err()
}
예제 #4
0
func (state *inSession) generateLogoutWithReason(session *Session, reason string) {
	reply := NewMessageBuilder()
	reply.Header().Set(field.NewMsgType("5"))
	reply.Header().Set(field.NewBeginString(session.sessionID.BeginString))
	reply.Header().Set(field.NewTargetCompID(session.sessionID.TargetCompID))
	reply.Header().Set(field.NewSenderCompID(session.sessionID.SenderCompID))

	if reason != "" {
		reply.Body().Set(field.NewText(reason))
	}

	session.send(reply)
	session.log.OnEvent("Sending logout response")
}
예제 #5
0
func (s *Session) run(msgIn chan fixIn, quit chan bool) {
	defer func() {
		close(quit)
		s.messageOut <- nil
		s.onDisconnect()
	}()

	if s.initiateLogon {

		if s.resetOnLogon {
			s.store.Reset()
		}

		logon := NewMessageBuilder()
		logon.Header().Set(field.NewMsgType("A"))
		logon.Header().Set(field.NewBeginString(s.sessionID.BeginString))
		logon.Header().Set(field.NewTargetCompID(s.sessionID.TargetCompID))
		logon.Header().Set(field.NewSenderCompID(s.sessionID.SenderCompID))
		logon.Body().Set(field.NewEncryptMethod(0))
		logon.Body().Set(field.NewHeartBtInt(s.heartBtInt))

		s.heartBeatTimeout = time.Duration(s.heartBtInt) * time.Second

		if len(s.defaultApplVerID) > 0 {
			logon.Body().Set(field.NewDefaultApplVerID(s.defaultApplVerID))
		}

		s.log.OnEvent("Sending logon request")
		s.send(logon)
	}

	for {

		switch s.currentState.(type) {
		case latentState:
			return
		}

		select {
		case fixIn, ok := <-msgIn:
			if ok {
				s.log.OnIncoming(string(fixIn.bytes))
				if msg, err := parseMessage(fixIn.bytes); err != nil {
					s.log.OnEventf("Msg Parse Error: %v, %q", err.Error(), fixIn.bytes)
				} else {
					msg.ReceiveTime = fixIn.receiveTime
					s.currentState = s.currentState.FixMsgIn(s, *msg)
				}
			} else {
				return
			}
			s.peerTimer.Reset(time.Duration(int64(1.2 * float64(s.heartBeatTimeout))))

		case msg := <-s.toSend:
			s.send(msg)

		case <-quit:
			return

		case evt := <-s.sessionEvent:
			s.currentState = s.currentState.Timeout(s, evt)
		}
	}
}
예제 #6
0
func (s *Session) handleLogon(msg Message) error {
	//Grab default app ver id from fixt.1.1 logon
	if s.sessionID.BeginString == fix.BeginString_FIXT11 {
		targetApplVerID := &field.DefaultApplVerIDField{}

		if err := msg.Body.Get(targetApplVerID); err != nil {
			return err
		}

		s.targetDefaultApplVerID = targetApplVerID.Value
	}

	if !s.initiateLogon {
		s.log.OnEvent("Received logon request")
		if s.resetOnLogon {
			s.store.Reset()
		}

		resetSeqNumFlag := new(fix.BooleanValue)
		if err := msg.Body.GetField(tag.ResetSeqNumFlag, resetSeqNumFlag); err == nil {
			if resetSeqNumFlag.Value {
				s.log.OnEvent("Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1")
				s.store.Reset()
			}
		}

		if err := s.verifyIgnoreSeqNumTooHigh(msg); err != nil {
			return err
		}

		reply := NewMessageBuilder()
		reply.Header().Set(field.NewMsgType("A"))
		reply.Header().Set(field.NewBeginString(s.sessionID.BeginString))
		reply.Header().Set(field.NewTargetCompID(s.sessionID.TargetCompID))
		reply.Header().Set(field.NewSenderCompID(s.sessionID.SenderCompID))
		reply.Body().Set(field.NewEncryptMethod(0))

		heartBtInt := &field.HeartBtIntField{}
		if err := msg.Body.Get(heartBtInt); err == nil {
			s.heartBeatTimeout = time.Duration(heartBtInt.Value) * time.Second
			reply.Body().Set(heartBtInt)
		}

		if resetSeqNumFlag.Value {
			reply.Body().Set(field.NewResetSeqNumFlag(resetSeqNumFlag.Value))
		}

		if len(s.defaultApplVerID) > 0 {
			reply.Body().Set(field.NewDefaultApplVerID(s.defaultApplVerID))
		}

		s.log.OnEvent("Responding to logon request")
		s.send(reply)
	}

	s.application.OnLogon(s.sessionID)

	if err := s.checkTargetTooHigh(msg); err != nil {
		switch TypedError := err.(type) {
		case targetTooHigh:
			s.doTargetTooHigh(TypedError)
		}
	}

	s.store.IncrNextTargetMsgSeqNum()
	return nil
}