Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MG-2186 - Migrate gocoap library from v2 to v3.3 #2183

Merged
merged 19 commits into from
May 22, 2024

Conversation

1998-felix
Copy link
Contributor

@1998-felix 1998-felix commented Apr 17, 2024

What type of PR is this?

This is a dependency update because it updates the following dependencies: plgd-dev/go-coap from v2 to v3.3

What does this do?

This update the current CoAP library from V2 to V3.3

Which issue(s) does this PR fix/relate to?

Have you included tests for your changes?

No,

Did you document any new/modified feature?

No

Notes

N/A

@1998-felix 1998-felix force-pushed the NOISSUE-gocoap_v3 branch 2 times, most recently from fc03222 to 07c3235 Compare April 18, 2024 08:03
@1998-felix 1998-felix marked this pull request as ready for review April 18, 2024 08:14
@arvindh123 arvindh123 added this to the S3 milestone Apr 18, 2024
coap/api/transport.go Outdated Show resolved Hide resolved
Copy link
Contributor

@arvindh123 arvindh123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coap/api/transport.go Outdated Show resolved Hide resolved
@arvindh123
Copy link
Contributor

suggestion for https://github.com/1998-felix/magistrala/blob/NOISSUE-gocoap_v3/coap/api/transport.go#L70-L144

func sendResp(w mux.ResponseWriter, resp *pool.Message) {
	if err := w.Conn().WriteMessage(resp); err != nil {
		logger.Warn(fmt.Sprintf("Can't set response: %s", err))
	}
}

func handler(w mux.ResponseWriter, m *mux.Message) {
	resp := pool.NewMessage(w.Conn().Context())
	resp.SetToken(m.Token())
	defer sendResp(w, resp)

	msg, err := decodeMessage(m)
	if err != nil {
		logger.Warn(fmt.Sprintf("Error decoding message: %s", err))
		resp.SetCode(codes.BadRequest)
		return
	}
	key, err := parseKey(m)
	if err != nil {
		logger.Warn(fmt.Sprintf("Error parsing auth: %s", err))
		resp.SetCode(codes.Unauthorized)
		return
	}
	switch m.Code() {
	case codes.GET:
		err = handleGet(context.Background(), m, w, msg, key)
		resp.SetCode(codes.Content)
	case codes.POST:
		resp.SetCode(codes.Created)
		err = service.Publish(m.Context(), key, msg)
	default:
		err = svcerr.ErrNotFound
	}
	if err != nil {
		switch {
		case err == errBadOptions:
			resp.SetCode(codes.BadOption)
		case err == svcerr.ErrNotFound:
			resp.SetCode(codes.NotFound)
		case errors.Contains(err, svcerr.ErrAuthorization),
			errors.Contains(err, svcerr.ErrAuthentication):
			resp.SetCode(codes.Unauthorized)
		default:
			resp.SetCode(codes.InternalServerError)
		}
	}
}

func handleGet(ctx context.Context, m *mux.Message, c mux.ResponseWriter, msg *messaging.Message, key string) error {
	var obs uint32
	obs, err := m.Observe()
	if err != nil {
		logger.Warn(fmt.Sprintf("Error reading observe option: %s", err))
		return errBadOptions
	}
	if obs == startObserve {
		c := coap.NewClient(c, m.Token(), logger)
		return service.Subscribe(ctx, key, msg.GetChannel(), msg.GetSubtopic(), c)
	}
	return service.Unsubscribe(ctx, key, msg.GetChannel(), msg.GetSubtopic(), m.Token().String())
}

@arvindh123 arvindh123 changed the title NOISSUE - Migrate gocoap library from v2 to v3.3 MG-2186 - Migrate gocoap library from v2 to v3.3 Apr 18, 2024
@1998-felix 1998-felix force-pushed the NOISSUE-gocoap_v3 branch 2 times, most recently from 2a0d91f to 2c3da40 Compare April 19, 2024 06:27
coap/api/transport.go Outdated Show resolved Hide resolved
coap/client.go Outdated Show resolved Hide resolved
coap/client.go Outdated Show resolved Hide resolved
coap/client.go Outdated Show resolved Hide resolved
coap/client.go Outdated Show resolved Hide resolved
coap/client.go Outdated Show resolved Hide resolved
coap/api/transport.go Outdated Show resolved Hide resolved
Copy link
Member

@rodneyosodo rodneyosodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try and test this. It fails after sending the first messages

Subscribe with coap

coap-cli get channels/$CHANNEL_ID/messages -auth $THING_SECRET -o

Publish from coap and mqtt

max=100;
for (( i=1; i <= max; ++i )); do
   timestamp=$(date +%s%N | cut -b1-13)
   payload='[{"bn":"random-test","bt":'$timestamp', "bu":"A","bver":5, "n":"voltage","u":"V","v":'$i'}]'
   mosquitto_pub -I magistrala -u $THING_ID -P $THING_SECRET -t channels/$CHANNEL_ID/messages -h localhost -m "$payload"
   coap-cli post channels/$CHANNEL_ID/messages -auth $THING_SECRET -d "$payload"
done

coap/api/transport.go Outdated Show resolved Hide resolved
coap/api/transport.go Outdated Show resolved Hide resolved
coap/api/transport.go Outdated Show resolved Hide resolved
Copy link
Contributor

@arvindh123 arvindh123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting error in coap logs, I suspect observer handler

{"time":"2024-04-24T14:52:51.106417452Z","level":"WARN","msg":"Failed to handle Magistrala message: cannot write request: context canceled"}

coap/api/transport.go Outdated Show resolved Hide resolved
@1998-felix 1998-felix force-pushed the NOISSUE-gocoap_v3 branch 2 times, most recently from b219951 to 6e9ff6e Compare April 29, 2024 06:41
Copy link
Contributor

@arvindh123 arvindh123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion for https://github.com/absmach/magistrala/blob/main/internal/server/coap/coap.go#L43

This will makes server not respond to inactivities

type udpNilMonitor struct{}

func (u *udpNilMonitor) UDPServerApply(cfg *udpServer.Config) {
	cfg.CreateInactivityMonitor = nil
}

var _ udpServer.Option = (*udpNilMonitor)(nil)

func NewUDPNilMonitor() udpServer.Option {
	return &udpNilMonitor{}
}

func (s *Server) Start() error {
	errCh := make(chan error)
	s.Logger.Info(fmt.Sprintf("%s service started using http, exposed port %s", s.Name, s.Address))
	s.Logger.Info(fmt.Sprintf("%s service %s server listening at %s without TLS", s.Name, s.Protocol, s.Address))

	opts := []any{}
	opts = append(opts, options.WithMux(s.handler), NewUDPNilMonitor())
	go func() {
		errCh <- gocoap.ListenAndServeWithOptions("udp", s.Address, opts...)
	}()

	select {
	case <-s.Ctx.Done():
		return s.Stop()
	case err := <-errCh:
		return err
	}
}

Copy link
Member

@rodneyosodo rodneyosodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, update

cmd := exec.Command("coap-cli", "post", fmt.Sprintf("channels/%s/messages", chanID), "-auth", thing.Credentials.Secret, "-d", msg)

rodneyosodo
rodneyosodo previously approved these changes May 17, 2024
coap/client.go Show resolved Hide resolved
Copy link
Contributor

@arvindh123 arvindh123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this way to close the UDP connection, But this don't work.

	go func() {
		errCh <- gocoap.ListenAndServeWithOptions(
			"udp",
			s.Address,
			options.WithMux(s.handler),
			options.WithInactivityMonitor(16*time.Second, func(cc *udpClient.Conn) {
				s.Logger.Info(fmt.Sprintf("starting to close inactive client"))
				pm := pool.NewMessage(context.Background())

				s.Logger.Info(fmt.Sprintf("got context of inactive client"))
				pm.SetCode(codes.Content)
				s.Logger.Info(fmt.Sprintf("set message code for  inactive client"))

				token, err := cc.GetToken()

				pm.SetMessageID(cc.GetMessageID())
				if err != nil {
					s.Logger.Error(fmt.Sprintf("failed to get token of inactive client : %s", err))
				}
				s.Logger.Info(fmt.Sprintf("set message token for  inactive client"))

				if err := cc.Session().WriteMessage(pm); err != nil {
					s.Logger.Error(fmt.Sprintf("failed to send close message to inactive client with token %s : %s.", token, err))
				}
				s.Logger.Info(fmt.Sprintf("written message  inactive client"))
				if err := cc.Close(); err != nil {
					s.Logger.Error(fmt.Sprintf("failed to send close connection to inactive client with token %s : %s.", token, err))
				}
				s.Logger.Info(fmt.Sprintf("closed connection of inactive client %s : %s.", token, err))

			}),
		)
	}()

Rest of Code Looks Good to me

Signed-off-by: 1998-felix <[email protected]>
Signed-off-by: 1998-felix <[email protected]>
@dborovcanin dborovcanin merged commit 42be65a into absmach:main May 22, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature: Migrate gocoap library from v2 to v3.3
4 participants