Files
tavern/core/apiimpl.go

527 lines
15 KiB
Go

package core
import (
"net/http"
common "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// CreateGroup : 그룹 생성
// - 그룹 : 멤버와 권한을 관리할 수 있다. 그룹 타입에 따라 디비에 저장되거나 메모리에만 존재한다.
// - 생성 요청이 오면 파티를 만든다. 파티을 만들 수 있는지 여부는 서비스에서 결정할 것이고, 이 요청을 호출했다는 것은 서비스가 결정한 그룹 생성 조건을 다 통과했다는 의미이다.
// - parameter :
// - type : 그룹 종류. 그룹 종류에 따라 인덱스와 쿼리 가능 field가 다르다.
func (sub *subTavern) CreateGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
grouptype := sub.groups[typename]
if grouptype == nil {
logger.Println("CreateGroup failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
doc := bson.M{}
if err := readBsonDoc(r.Body, &doc); err != nil {
logger.Error("CreateGroup failed. readBsonDoc returns err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
inserted, err := grouptype.Create(r.Form, doc)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
w.Write(inserted[:])
}
// JoinGroup : 그룹에 참가
// - type : 그룹 타입
// - 그룹 타입에 맞는 키(주로 _id)
// - member_id : 참가 멤버의 아이디
// - body : 멤버의 속성 bson document
func (sub *subTavern) JoinGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("JoinGroup failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
doc := bson.M{}
if err := readBsonDoc(r.Body, &doc); err != nil {
logger.Error("JoinGroup failed. readBsonDoc returns err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
gidobj, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("JoinGroup failed. gid is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
midobj, midok := common.ReadObjectIDFormValue(r.Form, "mid")
tidobj, tidok := common.ReadObjectIDFormValue(r.Form, "tid")
if !midok && !tidok {
// 둘다 없네?
logger.Println("JoinGroup failed. tid or mid should be exist")
w.WriteHeader(http.StatusBadRequest)
return
}
var err error
if candidate, ok := common.ReadBoolFormValue(r.Form, "candidate"); ok && candidate {
err = group.Candidate(gidobj, midobj, doc)
} else {
err = group.Join(gidobj, midobj, doc)
}
if err == nil {
writeBsonDoc(w, map[string]string{
"gid": gidobj.Hex(),
"tid": tidobj.Hex(),
})
} else if err == errGroupNotExist {
w.Write([]byte("{}"))
} else if err != nil {
logger.Error("JoinGroup failed :", err)
w.WriteHeader(http.StatusInternalServerError)
}
}
// Invite : 초대
// - type : 초대 타입 (required)
// - from : 초대하는 자 (required)
// - to : 초대받는 자 (required)
// - timeout : 초대 유지시간(optional. 없으면 config 기본 값)
// - (body) : 검색시 노출되는 document
func (sub *subTavern) Invite(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("Invite failed. group type is missing :", r)
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("Invite failed. gid is missing :", r)
w.WriteHeader(http.StatusBadRequest)
return
}
mid, ok := common.ReadObjectIDFormValue(r.Form, "mid")
if !ok {
logger.Println("Invite failed. mid is missing :", r)
w.WriteHeader(http.StatusBadRequest)
return
}
var reqdoc struct {
Inviter bson.M `bson:"inviter"`
Invitee bson.M `bson:"invitee"`
}
if err := readBsonDoc(r.Body, &reqdoc); err != nil {
logger.Println("Invite failed. readBsonDoc returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
result, err := group.Invite(gid, mid, reqdoc.Inviter, reqdoc.Invitee)
if err != nil {
logger.Println("Invite failed. group.Invite returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write([]byte(result))
}
func (sub *subTavern) CancelInvitation(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("CancelInvitation failed. group type is missing :", r)
w.WriteHeader(http.StatusBadRequest)
return
}
tid, ok := common.ReadObjectIDFormValue(r.Form, "tid")
if !ok {
logger.Println("CancelInvitation failed. form value 'tid' is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("CancelInvitation failed. form value 'gid' is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
if err := group.CancelInvitation(gid, tid); err != nil {
logger.Println("CancelInvitation failed. group.CancelInvitation returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
}
}
func (sub *subTavern) AcceptInvitation(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("CancelInvitation failed. group type is missing :", r)
w.WriteHeader(http.StatusBadRequest)
return
}
gid, _ := common.ReadObjectIDFormValue(r.Form, "gid")
mid, _ := common.ReadObjectIDFormValue(r.Form, "mid")
var member bson.M
if err := readBsonDoc(r.Body, &member); err != nil {
logger.Error("AcceptInvitation failed. readBsonDoc returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err := group.AcceptInvitation(gid, mid, member)
if err != nil {
logger.Println("AcceptInvitation failed. group.AcceptInvitation returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) DenyInvitation(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("DenyInvitation failed. group type is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gid, _ := common.ReadObjectIDFormValue(r.Form, "gid")
mid, _ := common.ReadObjectIDFormValue(r.Form, "mid")
tid, ok := common.ReadObjectIDFormValue(r.Form, "tid")
if !ok {
logger.Println("DenyInvitation failed. tid is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
err := group.DenyInvitation(gid, mid, tid)
if err != nil {
logger.Error("DenyInvitation failed. group.DenyInvitation returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) QueryInvitations(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("QueryInvitations failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
mid, ok := common.ReadObjectIDFormValue(r.Form, "mid")
if !ok {
logger.Println("QueryInvitations failed. mid is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
var after primitive.Timestamp
if v, ok := common.ReadStringFormValue(r.Form, "after"); ok && v != "0.0" {
after = common.DotStringToTimestamp(v)
}
result, err := group.QueryInvitations(mid, after)
if err != nil {
logger.Println("QueryInvitations failed. group.QueryInvitations returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if err := writeBsonArr(w, result); err != nil {
logger.Println("QueryInvitations failed. Encode returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) SearchGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("SearchGroup failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
projection, _ := common.ReadStringFormValue(r.Form, "projection")
var filter bson.M
if err := readBsonDoc(r.Body, &filter); err != nil {
logger.Error("SearchGroup failed. readBsonDoc returns err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
result, err := group.FindAll(filter, projection, primitive.Timestamp{})
if err != nil {
logger.Error("SearchGroup failed. FindAll err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if result == nil {
return
}
if err := writeBsonArr(w, result); err != nil {
logger.Error("bson marshal failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) QueryOnlineState(w http.ResponseWriter, r *http.Request) {
mid, ok := common.ReadObjectIDFormValue(r.Form, "mid")
if !ok {
logger.Println("IsOnline failed. mid is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
state := sub.wsh.GetState(sub.region, mid)
w.Write([]byte(state))
}
func (sub *subTavern) IsOnline(w http.ResponseWriter, r *http.Request) {
mid, ok := common.ReadObjectIDFormValue(r.Form, "mid")
if !ok {
logger.Println("IsOnline failed. mid is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
if state := sub.wsh.GetState(sub.region, mid); len(state) > 0 {
w.Write([]byte("true"))
} else {
w.Write([]byte("false"))
}
}
// QueryGroup : 그룹조회
// - type : 그룹 타입
// - 그룹 타입에 맞는 키(주로 _id)
// - projection : select할 필드. ,로 구분
func (sub *subTavern) QueryGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("QueryGroup failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "_id")
if !ok {
logger.Println("QueryGroup failed. _id is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
projection, _ := common.ReadStringFormValue(r.Form, "projection")
after, _ := common.ReadStringFormValue(r.Form, "after")
if after != "0.0" {
projection += ",+luts"
}
result, err := group.FindOne(gid, projection)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
if result == nil {
return
}
if len(after) > 0 {
if luts, ok := result["luts"].(primitive.Timestamp); ok {
afterts := common.DotStringToTimestamp(after)
if primitive.CompareTimestamp(luts, afterts) < 0 {
return
}
}
}
if err := writeBsonDoc(w, result); err != nil {
logger.Error("bson marshal failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
// LeaveGroup : 그룹에서 나감 or 내보냄
// - type : 그룹 타입
// - 그룹 타입에 맞는 키(주로 _id)
// - member_id : 나갈 멤버의 아이디
func (sub *subTavern) LeaveGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("LeaveGroup failed. group type is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("LeaveGroup failed. gid is missing :", r.Form)
w.WriteHeader(http.StatusBadRequest)
return
}
mid, midok := common.ReadObjectIDFormValue(r.Form, "mid")
if !midok {
logger.Println("LeaveGroup failed. mid is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
if err := group.Leave(gid, mid); err != nil {
// 둘 중 하나는 있어야지
logger.Println("LeaveGroup failed. group.Leave returns err :", err)
w.WriteHeader(http.StatusBadRequest)
}
}
func (sub *subTavern) UpdateMemberDocument(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("DismissGroup failed. type is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
midobj, ok := common.ReadObjectIDFormValue(r.Form, "mid")
if !ok {
logger.Println("UpdateMemberDocument failed. member_id is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gidobj, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("UpdateMemberDocument failed. _id is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
var updatedoc bson.M
if err := readBsonDoc(r.Body, &updatedoc); err != nil {
logger.Error("UpdateMemberDocument failed. body decoding error :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if err := group.UpdateMemberDocument(gidobj, midobj, updatedoc); err != nil {
logger.Println("UpdateMemberDocument failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) DismissGroup(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("DismissGroup failed. type is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("DismissGroup failed. gid is missing :")
w.WriteHeader(http.StatusBadRequest)
return
}
if err := group.Dismiss(gid); err != nil {
logger.Error("DismissGroup failed. group.Dismiss returns err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (sub *subTavern) UpdateGroupDocument(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("UpdateGroupDocument failed. type is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("UpdateGroupDocument failed. gid is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
var frag bson.M
if err := readBsonDoc(r.Body, &frag); err != nil {
logger.Error("UpdateGroupDocument failed. readBsonDoc err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if err := group.UpdateGroupDocument(gid, frag); err != nil {
logger.Error("UpdateGroupDocument failed. group.UpdateGroupDocument returns err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
}
func (sub *subTavern) QueryGroupMembers(w http.ResponseWriter, r *http.Request) {
typename, _ := common.ReadStringFormValue(r.Form, "type")
group := sub.groups[typename]
if group == nil {
logger.Println("QueryGroupMembers failed. type is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
gid, ok := common.ReadObjectIDFormValue(r.Form, "gid")
if !ok {
logger.Println("QueryGroupMembers failed. gid is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
members, err := group.QueryGroupMembers(gid)
if err != nil {
logger.Error("QueryGroupMembers failed. group.QueryGroupMembers returns err :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if err := writeBsonDoc(w, members); err != nil {
logger.Error("QueryGroupMembers failed. writeBsonDoc return err :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}