Advertisement
zhouhuakang

hello_erlang_app.erl

Feb 3rd, 2015
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 13.95 KB | None | 0 0
  1. %%%%%%%%%%%%%%%%
  2. %%%%%%%%%%%%%%%%
  3. hello_erlang.app.src
  4. %%%%%%%%%%%%%%%%
  5. %%%%%%%%%%%%%%%%
  6.  
  7. {application, hello_erlang, [
  8.   {description, ""},
  9.   {vsn, "0.1.0"},
  10.   {id, "git"},
  11.   {modules, []},
  12.   {registered, []},
  13.   {applications, [
  14.     kernel,
  15.     stdlib,
  16.     cowboy,
  17.     mongodb,
  18.     jiffy
  19.   ]},
  20.   {mod, {hello_erlang_app, []}},
  21.   {env,
  22.     [
  23.       {
  24.         mongodb_pools,
  25.         [
  26.           {
  27.            mg_pool1,
  28.            [
  29.              {size, 10},
  30.              {max_overflow, 20}
  31.            ],
  32.            [
  33.              {hostname, "127.0.0.1"},
  34.              {database, "user"},
  35.              {username, "zhk"},
  36.              {password, "zhk"}
  37.            ]
  38.           }
  39.         ]
  40.       }
  41.     ]
  42.   }
  43. ]}.
  44.  
  45.  
  46.  
  47. %%%%%%%%%%%%%%%%
  48. %%%%%%%%%%%%%%%%
  49. db_mongo_handler.erl
  50. %%%%%%%%%%%%%%%%
  51. %%%%%%%%%%%%%%%%
  52. %%%-------------------------------------------------------------------
  53. %%% @author zhouhuakang
  54. %%% @copyright (C) 2015, <COMPANY>
  55. %%% @doc
  56. %%%
  57. %%% @end
  58. %%% Created : 27. Jan 2015 10:44 AM
  59. %%%-------------------------------------------------------------------
  60. -module(db_mongo_handler).
  61. -author("zhouhuakang").
  62.  
  63. -behaviour(gen_server).
  64. %% API
  65. -export([start_link/1]).
  66.  
  67. %% gen_server callbacks
  68. -export([init/1,
  69.   handle_call/3,
  70.   handle_cast/2,
  71.   handle_info/2,
  72.   terminate/2,
  73.   code_change/3]).
  74.  
  75.  
  76.  
  77. -define(SERVER, ?MODULE).
  78.  
  79. -record(state, {connection}).
  80.  
  81. %%%===================================================================
  82. %%% API
  83. %%%===================================================================
  84.  
  85. %%--------------------------------------------------------------------
  86. %% @doc
  87. %% Starts the server
  88. %%
  89. %% @end
  90. %%--------------------------------------------------------------------
  91. -spec(start_link(Args :: list()) ->
  92.   {ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
  93. start_link(Args) ->
  94.   gen_server:start_link(?MODULE, Args, []).
  95.  
  96.  
  97. %%%===================================================================
  98. %%% gen_server callbacks
  99. %%%===================================================================
  100.  
  101. %%--------------------------------------------------------------------
  102. %% @private
  103. %% @doc
  104. %% Initializes the server
  105. %%
  106. %% @spec init(Args) -> {ok, State} |
  107. %%                     {ok, State, Timeout} |
  108. %%                     ignore |
  109. %%                     {stop, Reason}
  110. %% @end
  111. %%--------------------------------------------------------------------
  112. -spec(init(Args :: term()) ->
  113.   {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
  114.   {stop, Reason :: term()} | ignore).
  115. init(Args) ->
  116.   Hostname = proplists:get_value(hostname, Args),
  117.   Database = proplists:get_value(database, Args),
  118.   %% no user and pass for the moment
  119.   Username = proplists:get_value(username, Args),
  120.   Password = proplists:get_value(password, Args),
  121.   {ok, Connection} = mongo:connect(Hostname, 27017, Database),
  122.  
  123.   io:format("***************************Debug*********************************~n
  124.  Module:~p ~n  Line:~p ~n  Database Connection:~p ~n", [?MODULE, ?LINE, Connection]),
  125.   %% user-specific setup
  126.   SetupFun = proplists:get_value(setup, Args),
  127.   case SetupFun of
  128.     undefined -> ok;
  129.     {Mod, Fun} -> erlang:apply(Mod, Fun, [Connection, Args])
  130.   end,
  131.  
  132.   {ok, #state{connection = Connection}}.
  133.  
  134. %%--------------------------------------------------------------------
  135. %% @private
  136. %% @doc
  137. %% Handling call messages
  138. %%
  139. %% @end
  140. %%--------------------------------------------------------------------
  141. -spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
  142.     State :: #state{}) ->
  143.   {reply, Reply :: term(), NewState :: #state{}} |
  144.   {reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
  145.   {noreply, NewState :: #state{}} |
  146.   {noreply, NewState :: #state{}, timeout() | hibernate} |
  147.   {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
  148.   {stop, Reason :: term(), NewState :: #state{}}).
  149.  
  150.  
  151. handle_call({get_user, {Collection, Selector}}, _From, #state{connection = Connection} = State) ->
  152.   io:format("***************************Debug*********************************~n
  153.  Module:~p ~n  Line:~p ~n   Handle_call Connection:~p ~n Collection:~p ~n
  154.  Selector:~p ~n Connection is is_pid()? ~p ~n Collection is binary()? ~p ~n",
  155.     [?MODULE, ?LINE, Connection, Collection, Selector, is_pid(Connection), is_binary(Collection)]),
  156.   Cursor = mongo:find(Connection, Collection, Selector ),
  157.   io:format("***************************Debug*********************************~n Module:~p ~n  Line:~p ~n
  158.  Cursor:~p ~n", [?MODULE, ?LINE, Cursor]),
  159.   Result = mc_cursor:rest(Cursor),
  160.   [Head | _] = Result,
  161.   {_, _, _, NameValue, _, AgeValue} = Head,
  162.   io:format("***************************Debug*********************************~n Module:~p ~n  Line:~p ~n
  163.  NameValue:~p ~n  AgeValue:~p ~n ", [?MODULE, ?LINE, NameValue, AgeValue]),
  164.   BackData = binary_to_list(<<NameValue/bits, <<":">>/bits, AgeValue/bits>>),
  165.   {reply, BackData, State}.
  166.  
  167. %%--------------------------------------------------------------------
  168. %% @private
  169. %% @doc
  170. %% Handling cast messages
  171. %%
  172. %% @end
  173. %%--------------------------------------------------------------------
  174. -spec(handle_cast(Request :: term(), State :: #state{}) ->
  175.   {noreply, NewState :: #state{}} |
  176.   {noreply, NewState :: #state{}, timeout() | hibernate} |
  177.   {stop, Reason :: term(), NewState :: #state{}}).
  178. handle_cast(_Request, State) ->
  179.   {noreply, State}.
  180.  
  181. %%--------------------------------------------------------------------
  182. %% @private
  183. %% @doc
  184. %% Handling all non call/cast messages
  185. %%
  186. %% @spec handle_info(Info, State) -> {noreply, State} |
  187. %%                                   {noreply, State, Timeout} |
  188. %%                                   {stop, Reason, State}
  189. %% @end
  190. %%--------------------------------------------------------------------
  191. -spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
  192.   {noreply, NewState :: #state{}} |
  193.   {noreply, NewState :: #state{}, timeout() | hibernate} |
  194.   {stop, Reason :: term(), NewState :: #state{}}).
  195. handle_info(_Info, State) ->
  196.   {noreply, State}.
  197.  
  198. %%--------------------------------------------------------------------
  199. %% @private
  200. %% @doc
  201. %% This function is called by a gen_server when it is about to
  202. %% terminate. It should be the opposite of Module:init/1 and do any
  203. %% necessary cleaning up. When it returns, the gen_server terminates
  204. %% with Reason. The return value is ignored.
  205. %%
  206. %% @spec terminate(Reason, State) -> void()
  207. %% @end
  208. %%--------------------------------------------------------------------
  209. -spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
  210.     State :: #state{}) -> term()).
  211. terminate(_Reason, _State) ->
  212.   ok.
  213.  
  214. %%--------------------------------------------------------------------
  215. %% @private
  216. %% @doc
  217. %% Convert process state when code is changed
  218. %%
  219. %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
  220. %% @end
  221. %%--------------------------------------------------------------------
  222. -spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
  223.     Extra :: term()) ->
  224.   {ok, NewState :: #state{}} | {error, Reason :: term()}).
  225. code_change(_OldVsn, State, _Extra) ->
  226.   {ok, State}.
  227.  
  228.  
  229. %%%===================================================================
  230. %%% Internal functions
  231. %%%===================================================================
  232.  
  233.  
  234. get_user(Name, Connection, Req) ->
  235.   Selector = {Name, <<"undefined">>},
  236.   Collection = <<"user">>,
  237.   Cursor = mongo:find(Connection, Collection, Selector),
  238.   Result = mc_cursor:rest(Cursor),
  239.   [Head | _] = Result,
  240.   {_, _, _, NameValue, _, AgeValue} = Head,
  241.   BackData = binary_to_list(<<NameValue/bits, <<":">>/bits, AgeValue/bits>>).
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253. %%%%%%%%%%%%%%%%
  254. %%%%%%%%%%%%%%%%
  255. hello_erlang_app.erl
  256. %%%%%%%%%%%%%%%%
  257. %%%%%%%%%%%%%%%%
  258. -module(hello_erlang_app).
  259. -behaviour(application).
  260.  
  261. -export([start/2]).
  262. -export([stop/1]).
  263.  
  264. start(_Type, _Args) ->
  265.  
  266.   %% init cowboy
  267.   Dispatch = cowboy_router:compile([
  268.     {'_', [{"/user/[:user_name]", hello_handler, []}]}
  269.   ]),
  270.   cowboy:start_http(my_http_listener, 100, [{port, 8080}],
  271.     [{env, [{dispatch, Dispatch}]}]
  272.   ),
  273.   io:format("Cowboy inited Line 22 ~n "),
  274.   hello_erlang_sup:start_link().
  275.  
  276. stop(_State) ->
  277.   ok.
  278.  
  279.  
  280.  
  281.  
  282. %%%%%%%%%%%%%%%%
  283. %%%%%%%%%%%%%%%%
  284. hello_erlang_sup.erl
  285. %%%%%%%%%%%%%%%%
  286. %%%%%%%%%%%%%%%%
  287. -module(hello_erlang_sup).
  288. -behaviour(supervisor).
  289.  
  290. -export([start_link/0]).
  291. -export([init/1]).
  292.  
  293. start_link() ->
  294.   supervisor:start_link({local, ?MODULE}, ?MODULE, []).
  295.  
  296. init([]) ->
  297.   %% init mongodb
  298.   {ok, Pools} = application:get_env(hello_erlang, mongodb_pools),
  299.   io:format("**********************************************************************Pools is ~n ~p ~n ", [Pools]),
  300.   PoolSpecs =
  301.     lists:map(
  302.       fun({Name, SizeArgs, WorkerArgs}) ->
  303.         PoolArgs = [{name, {local, Name}}, {worker_module, db_mongo_handler}] ++ SizeArgs,
  304.         io:format("****************************************************************Name is ~n  ~p ~n ", [Name]),
  305.         io:format("****************************************************************SizeArgs is ~n ~p ~n ", [SizeArgs]),
  306.         io:format("****************************************************************WorkerArgs is ~n ~p ~n ", [WorkerArgs]),
  307.         poolboy:child_spec(Name, PoolArgs, WorkerArgs)
  308.       end,
  309.       Pools),
  310.   io:format("**********************************************************************PoolsSpecs:re ~n ~p ~n", [PoolSpecs]),
  311.   io:format("**********************************************************************Poolboy has exited: ~n ~p ~n", [poolboy:module_info()]),
  312.   {ok, {{one_for_one, 10, 10}, PoolSpecs}}.
  313.  
  314. %%
  315. %%   {ok, Pools} = application:get_env(hello_erlang, mongodb_pools),
  316. %%   PoolSpecs = lists:map(fun({Name, SizeArgs, WorkerArgs}) ->
  317. %%     PoolArgs = [{name, {local, Name}},
  318. %%       {worker_module, db_mongo_handler}] ++ SizeArgs,
  319. %%     poolboy:child_spec(Name, PoolArgs, WorkerArgs)
  320. %%   end, Pools),
  321. %%   {ok, {{one_for_one, 10, 10}, [PoolSpecs]}}.
  322.  
  323.  
  324.  
  325. %%%%%%%%%%%%%%%%
  326. %%%%%%%%%%%%%%%%
  327. hello_handler.erl
  328. %%%%%%%%%%%%%%%%
  329. %%%%%%%%%%%%%%%%
  330. -module(hello_handler).
  331. -behaviour(cowboy_http_handler).
  332.  
  333. -export([init/3]).
  334. -export([handle/2]).
  335. -export([terminate/3]).
  336.  
  337. -define(DB_Conn_Pool, mg_pool1).
  338. init(_, Req, Opts) ->
  339.   {ok, Req, Opts}.
  340.  
  341. handle(Req, State) ->
  342.   case cowboy_req:method(Req) of
  343.     {<<"GET">>, Req2} ->
  344.       {UserName, Req3} = cowboy_req:binding(user_name, Req2),
  345.       io:format("***************************Debug*********************************~n  Module:~p ~n  Line:~p ~n  UserName:~p ~n", [?MODULE, ?LINE, UserName]),
  346.       get_user(UserName, Req3);
  347.     {<<"DELETE">>, Req2} ->
  348.       {UserName, Req3} = cowboy_req:binding(user_name, Req2),
  349.       delete_user(UserName, Req3);
  350.     {<<"POST">>, Req2} ->
  351.       {ok, Body, Req3} = cowboy_req:body(Req2),
  352.       UserInfo = jiffy:decode(Body),
  353.       {[{<<"name">>, NameValue}, {<<"age">>, AgeValue}]} = UserInfo,
  354.       io:format("--Body is ~p ~n  --UserInfo is ~p ~n --NameValue is ~p ~n --AgeValue is ~p ~n", [Body, UserInfo, NameValue, AgeValue]),
  355.       add_user(NameValue, AgeValue, Req3);
  356.     {<<"PUT">>, Req2} ->
  357.       {ok, Body, Req3} = cowboy_req:body(Req2),
  358.       UserInfo = jiffy:decode(Body),
  359.       {[{<<"name">>, NameValue}, {<<"age">>, AgeValue}]} = UserInfo,
  360.       io:format("--Body is ~p ~n  --UserInfo is ~p ~n --NameValue is ~p ~n --AgeValue is ~p ~n", [Body, UserInfo, NameValue, AgeValue]),
  361.       update_user(NameValue, AgeValue, Req3)
  362.  
  363.   end.
  364.  
  365.  
  366. get_user(Name, Req) ->
  367.   Collection = <<"user">>,
  368.   Selector = {name, Name},
  369.   Worker = poolboy:checkout(?DB_Conn_Pool),
  370.   io:format("***************************Debug*********************************~n  Module:~p ~n  Line:~p ~n  Worker:~p ~n", [?MODULE, ?LINE, Worker]),
  371.   Request = {get_user, {Collection, Selector}},
  372.   UserInfo = gen_server:call(Worker, Request),
  373.   io:format("***************************Debug*********************************~n  Module:~p ~n  Line:~p ~n  UserInfo:~p ~n", [?MODULE, ?LINE, UserInfo]),
  374.   cowboy_req:reply(200, [
  375.     {<<"content-type">>, <<"text/plain">>}
  376.   ], UserInfo, Req).
  377.  
  378.  
  379. %% Add user
  380. add_user(Name, Age, Req) ->
  381.   {Database, Collection} = {<<"user">>, <<"user">>},
  382.   {ok, Connection} = mongo:connect("127.0.0.1", 27017, Database),
  383.   mongo:insert(Connection, Collection, [{name, Name, age, Age}]).
  384.  
  385.  
  386. %%Update user
  387. update_user(Name, Age, Req) ->
  388.   {Database, Collection} = {<<"user">>, <<"user">>},
  389.   {ok, Connection} = mongo:connect("127.0.0.1", 27017, Database),
  390.   Command = {'$set', {age, Age}},
  391.   mongo:update(Connection, Collection, {name, Name}, Command).
  392.  
  393. %%Delete user
  394. delete_user(Name, Req) ->
  395.   {Database, Collection} = {<<"user">>, <<"user">>},
  396.   {ok, Connection} = mongo:connect("127.0.0.1", 27017, Database),
  397.   Selector = {name, Name},
  398.   mongo:delete(Connection, Collection, Selector).
  399.  
  400.  
  401. terminate(_Reason, _Req, _State) ->
  402.   ok.
  403.  
  404.  
  405.  
  406.  
  407.  
  408. %%%%%%%%%%%%%%%%
  409. %%%%%%%%%%%%%%%%
  410. start.erl
  411. %%%%%%%%%%%%%%%%
  412. %%%%%%%%%%%%%%%%
  413. -module(start).
  414. -author("zhouhuakang").
  415.  
  416. %% API
  417. -export([]).
  418. -export([
  419.   start_applications/1, stop_applications/1, server_start/0]).
  420. -define(SERVER_APPS, [sasl,ranch,crypto,cowlib,cowboy,bson,mongodb,jiffy,hello_erlang]).
  421.  
  422.  
  423. server_start()->
  424.   try
  425.     ok = start_applications(?SERVER_APPS)
  426.   after
  427.     timer:sleep(100)
  428.   end.
  429.  
  430.  
  431. manage_applications(Iterate, Do, Undo, SkipError, ErrorTag, Apps) ->
  432.   Iterate( fun (App, Acc) ->
  433.     case Do(App) of
  434.       ok -> [App | Acc];
  435.       {error, {SkipError, _}} -> Acc;
  436.       {error, Reason} ->
  437.         lists:foreach(Undo, Acc),
  438.         throw({error, {ErrorTag, App, Reason}})
  439.     end
  440.   end, [], Apps),
  441.   ok.
  442.  
  443. start_applications(Apps) ->
  444.   manage_applications(fun lists:foldl/3,
  445.     fun application:start/1,
  446.     fun application:stop/1,
  447.     already_started,
  448.     cannot_start_application,
  449.     Apps).
  450.  
  451. stop_applications(Apps) ->
  452.   manage_applications(fun lists:foldr/3,
  453.     fun application:stop/1,
  454.     fun application:start/1,
  455.     not_started,
  456.     cannot_stop_application,
  457.     Apps).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement