diff --git a/src/machi.proto b/src/machi.proto index db0fbb1..92b89b8 100644 --- a/src/machi.proto +++ b/src/machi.proto @@ -78,7 +78,7 @@ message Mpb_ChunkCSum { // epoch_id() type message Mpb_EpochID { - required uint32 epoch_num = 1; + required uint32 epoch_number = 1; required bytes epoch_csum = 2; } @@ -321,7 +321,7 @@ message Mpb_LL_GetLatestEpochIDReq { } message Mpb_LL_GetLatestEpochIDResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; optional Mpb_EpochID epoch_id = 2; } @@ -332,7 +332,7 @@ message Mpb_LL_ReadLatestProjectionReq { } message Mpb_LL_ReadLatestProjectionResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; optional Mpb_ProjectionV1 proj = 1; } @@ -344,7 +344,7 @@ message Mpb_LL_ReadProjectionReq { } message Mpb_LL_ReadProjectionResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; optional Mpb_ProjectionV1 proj = 2; } @@ -356,7 +356,7 @@ message Mpb_LL_WriteProjectionReq { } message Mpb_LL_WriteProjectionResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; } // Low level API: get_all_projections() request & response @@ -366,7 +366,7 @@ message Mpb_LL_GetAllProjectionsReq { } message Mpb_LL_GetAllProjectionsResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; repeated Mpb_ProjectionV1 proj = 2; } @@ -377,7 +377,7 @@ message Mpb_LL_ListAllProjectionsReq { } message Mpb_LL_ListAllProjectionsResp { - required uint32 Mpb_GeneralStatusCode = 1; + required Mpb_GeneralStatusCode status = 1; repeated uint32 epochs = 2; } @@ -400,12 +400,12 @@ message Mpb_LL_Request { // that not all languages might care about? (Erlang doesn't) optional Mpb_EchoReq echo = 10; // Re-use from high level API optional Mpb_AuthReq auth = 11; // Re-use from high level API - optional Mpb_LL_GetLatestEpochIDReq = 12; - optional Mpb_LL_ReadLatestProjectionReq = 13; - optional Mpb_LL_ReadProjectionReq = 14; - optional Mpb_LL_WriteProjectionReq = 15; - optional Mpb_LL_GetAllProjectionsReq = 16; - optional Mpb_LL_ListAllProjectionsReq = 17; + optional Mpb_LL_GetLatestEpochIDReq proj_gl = 12; + optional Mpb_LL_ReadLatestProjectionReq proj_rl = 13; + optional Mpb_LL_ReadProjectionReq proj_rp = 14; + optional Mpb_LL_WriteProjectionReq proj_wp = 15; + optional Mpb_LL_GetAllProjectionsReq proj_ga = 16; + optional Mpb_LL_ListAllProjectionsReq proj_la = 17; } message Mpb_LL_Response { @@ -424,5 +424,10 @@ message Mpb_LL_Response { // Specific responses. optional Mpb_EchoResp echo = 10; // Re-use from high level API optional Mpb_AuthResp auth = 11; // Re-use from high level API - optional Mpb_LL_GetLatestEpochIDResp = 12; + optional Mpb_LL_GetLatestEpochIDResp proj_gl = 12; + optional Mpb_LL_ReadLatestProjectionResp proj_rl = 13; + optional Mpb_LL_ReadProjectionResp proj_rp = 14; + optional Mpb_LL_WriteProjectionResp proj_wp = 15; + optional Mpb_LL_GetAllProjectionsResp proj_ga = 16; + optional Mpb_LL_ListAllProjectionsResp proj_la = 17; } diff --git a/src/machi_flu1_client.erl b/src/machi_flu1_client.erl index 4a7996b..df59d7d 100644 --- a/src/machi_flu1_client.erl +++ b/src/machi_flu1_client.erl @@ -802,38 +802,44 @@ trunc_hack2(Sock, EpochID, File) -> end. get_latest_epochid2(Sock, ProjType) -> - ProjCmd = {get_latest_epochid, ProjType}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {get_latest_epochid, ProjType}), + do_projection_common(Sock, Req). read_latest_projection2(Sock, ProjType) -> - ProjCmd = {read_latest_projection, ProjType}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {read_latest_projection, ProjType}), + do_projection_common(Sock, Req). read_projection2(Sock, ProjType, Epoch) -> - ProjCmd = {read_projection, ProjType, Epoch}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {read_projection, ProjType, Epoch}), + do_projection_common(Sock, Req). write_projection2(Sock, ProjType, Proj) -> - ProjCmd = {write_projection, ProjType, Proj}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {write_projection, ProjType, Proj}), + do_projection_common(Sock, Req). get_all_projections2(Sock, ProjType) -> - ProjCmd = {get_all_projections, ProjType}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {get_all_projections, ProjType}), + do_projection_common(Sock, Req). list_all_projections2(Sock, ProjType) -> - ProjCmd = {list_all_projections, ProjType}, - do_projection_common(Sock, ProjCmd). + Req = machi_pb_wrap:make_projection_req( + <<42>>, {list_all_projections, ProjType}), + do_projection_common(Sock, Req). -do_projection_common(Sock, ProjCmd) -> +do_projection_common(Sock, Req) -> erase(bad_sock), try - ProjCmdBin = term_to_binary(ProjCmd), - Len = iolist_size(ProjCmdBin), + ReqBin = machi_pb:encode_mpb_ll_request(Req), + Len = iolist_size(ReqBin), true = (Len =< ?MAX_CHUNK_SIZE), LenHex = machi_util:int_to_hexbin(Len, 32), Cmd = [<<"PROJ ">>, LenHex, <<"\n">>], - ok = w_send(Sock, [Cmd, ProjCmdBin]), + ok = w_send(Sock, [Cmd, ReqBin]), ok = w_setopts(Sock, [{packet, line}]), case w_recv(Sock, 0) of {ok, Line} -> @@ -841,9 +847,10 @@ do_projection_common(Sock, ProjCmd) -> <<"OK ", ResLenHex:8/binary, "\n">> -> ResLen = machi_util:hexstr_to_int(ResLenHex), ok = w_setopts(Sock, [{packet, raw}]), - {ok, ResBin} = w_recv(Sock, ResLen), + {ok, RespBin} = w_recv(Sock, ResLen), ok = w_setopts(Sock, [{packet, line}]), - binary_to_term(ResBin); + Resp = machi_pb:decode_mbp_ll_response(RespBin), + machi_pb_wrap:unmake_projection_resp(Resp); Else -> {error, Else} end diff --git a/src/machi_pb_high_client.erl b/src/machi_pb_high_client.erl index adf380d..14fa9f5 100644 --- a/src/machi_pb_high_client.erl +++ b/src/machi_pb_high_client.erl @@ -44,6 +44,7 @@ checksum_list/2, checksum_list/3, list_files/1, list_files/2 ]). +-export([convert_general_status_code/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -354,6 +355,8 @@ convert_append_chunk_resp(#mpb_appendchunkresp{status='OK', chunk_pos=CP}) -> convert_append_chunk_resp(#mpb_appendchunkresp{status=Status}) -> convert_general_status_code(Status). +convert_general_status_code('OK') -> + ok; convert_general_status_code('BAD_ARG') -> {error, bad_arg}; convert_general_status_code('WEDGED') -> diff --git a/src/machi_pb_wrap.erl b/src/machi_pb_wrap.erl index c2e21bc..94c4117 100644 --- a/src/machi_pb_wrap.erl +++ b/src/machi_pb_wrap.erl @@ -19,13 +19,23 @@ %% under the License. %% %% ------------------------------------------------------------------- + +%% @doc Wrappers for Protocol Buffers encoding, including hacks to fix +%% impedance mismatches between Erlang terms and PB encodings. +%% +%% TODO: Any use of enc_sexp() and dec_sexp() should be eliminated, +%% except for the possibility of items where we are 100% sure +%% that a non-Erlang software component can get away with always +%% treating that item as an opaque thing. + -module(machi_pb_wrap). -include("machi_pb.hrl"). -include("machi_projection.hrl"). -export([enc_p_srvr/1, dec_p_srvr/1, - enc_projection_v1/1, dec_projection_v1/1]). + enc_projection_v1/1, dec_projection_v1/1, + make_projection_req/2, unmake_projection_resp/1]). -ifdef(TEST). -compile(export_all). -endif. % TEST @@ -124,6 +134,57 @@ conv_to_projection_v1(#mpb_projectionv1{epoch_number=Epoch, dbg2=dec_sexp(Dbg2), members_dict=conv_to_members_dict(MembersDict)}. +make_projection_req(ID, {get_latest_epochid, ProjType}) -> + #mpb_ll_request{req_id=ID, + proj_gl=#mpb_ll_getlatestepochidreq{type=conv_from_type(ProjType)}}; +make_projection_req(ID, {read_latest_projection, ProjType}) -> + #mpb_ll_request{req_id=ID, + proj_rl=#mpb_ll_readlatestprojectionreq{type=conv_from_type(ProjType)}}; +make_projection_req(ID, {read_projection, ProjType, Epoch}) -> + #mpb_ll_request{req_id=ID, + proj_rp=#mpb_ll_readprojectionreq{type=conv_from_type(ProjType), + epoch_number=Epoch}}; +make_projection_req(ID, {write_projection, ProjType, Proj}) -> + ProjM = conv_from_projection_v1(Proj), + #mpb_ll_request{req_id=ID, + proj_wp=#mpb_ll_writeprojectionreq{type=conv_from_type(ProjType), + proj=ProjM}}; +make_projection_req(ID, {get_all_projections, ProjType}) -> + #mpb_ll_request{req_id=ID, + proj_ga=#mpb_ll_getallprojectionsreq{type=conv_from_type(ProjType)}}; +make_projection_req(ID, {list_all_projections, ProjType}) -> + #mpb_ll_request{req_id=ID, + proj_la=#mpb_ll_listallprojectionsreq{type=conv_from_type(ProjType)}}. + +unmake_projection_resp(#mpb_ll_response{proj_gl=#mpb_ll_getlatestepochidresp{ + status=Status, epoch_id=EID}}) -> + case Status of + 'OK' -> + #mpb_epochid{epoch_number=Epoch, epoch_csum=CSum} = EID, + {ok, {Epoch, CSum}}; + _ -> + machi_pb_high_client:convert_general_status_code(Status) + end; +unmake_projection_resp(#mpb_ll_response{proj_rl=#mpb_ll_readlatestprojectionresp{ + status=Status, proj=P}}) -> + case Status of + 'OK' -> + {ok, conv_to_projection_v1(P)}; + _ -> + machi_pb_high_client:convert_general_status_code(Status) + end; +unmake_projection_resp(#mpb_ll_response{proj_rp=#mpb_ll_readprojectionresp{ + status=Status, proj=P}}) -> + case Status of + 'OK' -> + {ok, conv_to_projection_v1(P)}; + _ -> + machi_pb_high_client:convert_general_status_code(Status) + end; +unmake_projection_resp(#mpb_ll_response{proj_wp=#mpb_ll_writeprojectionresp{ + status=Status}}) -> + machi_pb_high_client:convert_general_status_code(Status). + %%%%%%%%%%%%%%%%%%% enc_sexp(T) -> @@ -192,3 +253,8 @@ conv_from_mode(cp_mode) -> 'CP_MODE'. conv_to_mode('AP_MODE') -> ap_mode; conv_to_mode('CP_MODE') -> cp_mode. +conv_from_type(private) -> 'PRIVATE'; +conv_from_type(public) -> 'PUBLIC'. + +conv_to_type('PRIVATE') -> private; +conv_to_type('PUBLIC') -> public.