[
https://issues.apache.org/jira/browse/COUCHDB-769?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15103639#comment-15103639
]
ASF GitHub Bot commented on COUCHDB-769:
----------------------------------------
Github user gilv commented on a diff in the pull request:
https://github.com/apache/couchdb-fabric/pull/33#discussion_r49943389
--- Diff: src/fabric_swift_driver.erl ---
@@ -0,0 +1,269 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+% use this file except in compliance with the License. You may obtain a
copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations
under
+% the License.
+
+-module(fabric_swift_driver).
+
+-export([put_object/5, delete_object/2, get_object/2, head_object/2]).
+-export([store_id/0, create_container/1, delete_container/1 ]).
+%% ====================================================================
+%% OpenStack Swift implementation
+%% ====================================================================
+
+store_id() ->
+ "swift".
+
+put_object(Container, ObjName, ContextType, CustomHeaders, Data) ->
+ couch_log:debug("Swift: PUT ~p/~s object ~n", [Container, ObjName]),
+ case authenticate() of
+ {ok, {Url, Storage_Token}} ->
+ ObjNameEncoded = couch_util:url_encode(ObjName),
+ Headers = CustomHeaders ++ [{"X-Auth-Token", Storage_Token},
+ {"Content-Type",
+
unicode:characters_to_list(ContextType)}],
+ Method = put,
+ couch_log:debug("Swift: PUT : ~p ~p ~p ~p~n",
+ [Url,ContextType, ObjNameEncoded, Container]),
+ NewUrl = Url ++ "/" ++ unicode:characters_to_list(Container)
++ "/" ++ unicode:characters_to_list(ObjNameEncoded),
+ couch_log:debug("Swift: PUT url: ~p~n",[NewUrl]),
+ R = ibrowse:send_req(NewUrl, Headers, Method, Data),
+ case R of
+ {ok, ReturnCode, _, _} ->
+ {ok, {ReturnCode, NewUrl}};
+ Error ->
+ couch_log:debug("PUT object failed ~p ~n",
[element(2, Error)]),
+ {error, "PUT object failed"}
+ end;
+ {not_authenticated, _} ->
+ {error, "Not authenticated"}
+ end.
+
+delete_object(Container, ObjName) ->
+ %TO-DO: should be called during database compaction.
+ couch_log:debug("Swift: Delete ~p/~p ~n", [Container, ObjName]),
+ case authenticate() of
+ {ok, {Url, Storage_Token}} ->
+ Header = [{"X-Auth-Token", Storage_Token}],
+ ObjNameEncoded = couch_util:url_encode(ObjName),
+ Method = delete,
+ NewUrl = Url ++ "/" ++ unicode:characters_to_list(Container)
++ "/"
+ ++ unicode:characters_to_list(ObjNameEncoded),
+ couch_log:debug("Swift: url ~p~n", [NewUrl]),
+ R = ibrowse:send_req(NewUrl, Header, Method),
+ case R of
+ {ok, ReturnCode, _, _} ->
+ couch_log:debug("Swift: Delete ~p. Return code ~p ~n",
+ [NewUrl, ReturnCode]),
+ {ok, ReturnCode};
+ Error ->
+ couch_log:debug("Swift: Delete ~p failed. ~n",
[NewUrl]),
+ couch_log:debug("Swift: ~p ~n", [element(2, Error)]),
+ {error, "Delete object failed"}
+ end;
+ {not_authenticated, _} ->
+ {error, "Not authenticated"}
+ end.
+
+get_object(Container, ObjName) ->
+ couch_log:debug("Swift: get object ~p/~p ~n", [Container, ObjName]),
+ case authenticate() of
+ {ok, {Url, Storage_Token}} ->
+ Header = [{"X-Auth-Token", Storage_Token}],
+ ObjNameEncoded = couch_util:url_encode(ObjName),
+ Method = get,
+ NewUrl = Url ++ "/" ++ unicode:characters_to_list(Container)
++ "/"
+ ++ unicode:characters_to_list(ObjNameEncoded),
+ couch_log:debug("Swift: url ~p~n", [NewUrl]),
+ R = ibrowse:send_req(NewUrl, Header, Method),
+ case R of
+ {ok, ReturnCode, _, Body} ->
+ couch_log:debug("Swift: GET ~p with return code ~p
~n", [NewUrl, ReturnCode]),
+ Body;
+ Error ->
+ couch_log:debug("Swift: GET ~p failed. ~n", [NewUrl]),
+ couch_log:debug("Swift: ~p ~n", [element(2, Error)]),
+ {error, "Get object failed"}
+ end;
+ {not_authenticated, _} ->
+ {error, "Not authenticated"}
+ end.
+
+head_object(Container, ObjName) ->
+ couch_log:debug("Swift: head object ~p/~p ~n", [Container, ObjName]),
+ case authenticate() of
+ {ok, {Url, Storage_Token}} ->
+ Header = [{"X-Auth-Token", Storage_Token}],
+ Method = head,
+ ObjNameEncoded = couch_util:url_encode(ObjName),
+ NewUrl = Url ++ "/" ++ unicode:characters_to_list(Container)
+ ++ "/" ++ unicode:characters_to_list(ObjNameEncoded),
+ couch_log:debug("Swift: url ~p~n", [NewUrl]),
+ R = ibrowse:send_req(NewUrl, Header, Method),
+ case R of
+ {ok, ReturnCode, Head, _} ->
+ couch_log:debug("Swift: ~p~p~n", [ReturnCode, Head]),
+ ObjectSize = lists:filter(fun ({"Content-Length", _})
-> true; (_) -> false end, Head),
+ EtagHeader = lists:filter(fun ({"Etag", _}) -> true ;
(_) -> false end, Head),
+ Etag = element(2, lists:nth(1, EtagHeader)),
+ {ObjectSizeNumeric, _} = string:to_integer(element(2,
lists:nth(1, ObjectSize))),
+ couch_log:debug("Swift: Object size is: ~p and Etag:
~p~n",
+ [ObjectSizeNumeric, Etag]),
+ EtagDecode = hex_to_bin(Etag),
+ EtagMD5 = base64:encode(EtagDecode),
+ couch_log:debug("Etag in base64 ~p~n", [EtagMD5]),
+ {ok, {ObjectSizeNumeric, EtagMD5}};
+ Error ->
+ couch_log:debug("Swift: Head ~p failed ~n", [NewUrl]),
+ couch_log:debug("Swift: ~p ~n", [element(2, Error)]),
+ {error,"HEAD object failed"}
+ end;
+ {not_authenticated, _} ->
+ {error, "Not authenticated"}
+ end.
+
+create_container(DbName) ->
+ couch_log:debug("Swift : create container ~p~n", [DbName]),
+ case authenticate() of
+ {ok, {Url, Storage_Token}} ->
+ Header = [{"X-Auth-Token",Storage_Token}],
+ Method = put,
+ Container = DbName,
+ NewUrl = Url ++ "/" ++ unicode:characters_to_list(Container)
++"/",
+ couch_log:debug("Swift: url ~p ~n",[NewUrl]),
+ R = ibrowse:send_req(NewUrl, Header, Method),
+ case R of
+ {ok, ReturnCode, _, _} ->
+ couch_log:debug("Swift: container ~p created with code
: ~p~n",[Container, ReturnCode]),
+ {ok,{ReturnCode,Container}};
+ Error ->
+ couch_log:debug("Swift: container ~p creation failed :
~p~n",[Container, element(2,Error)]),
+ {error, "Failed to create container"}
+ end;
+ {not_authenticated,_} ->
+ {error, "Failed to create container. Not authenticated"}
+ end.
+
+delete_container(Container) ->
+ case authenticate() of
+ {ok,{Url,Storage_Token}} ->
+ Header = [{"X-Auth-Token",Storage_Token}],
+ Method = delete,
+ NewUrl = Url ++ "/" ++ Container ++"/",
+ R = ibrowse:send_req(NewUrl, Header, Method),
+ case R of
+ {ok, ReturnCode, _, _} ->
+ {ok,{ReturnCode,Container}};
+ Error ->
+ {error,{element(2,Error),Container}}
+ end;
+ {not_authenticated, _} ->
+ {error, "Not authenticated"};
+ {not_supported, Error} ->
+ {error,{element(2,Error),""}}
+ end.
+
+%% ====================================================================
+%% Internal functions
+%% ====================================================================
+
+hex_to_bin(Str) -> << << (erlang:list_to_integer([H], 16)):4 >> || H <-
Str >>.
+
+authenticate() ->
+ couch_log:debug("Going to authenticate in Swift",[]),
+ case config:get("swift", "auth_model", "tempauth") of
+ "tempauth" ->
+ swift_v1_auth();
+ "keystone" ->
+ keystone_auth();
+ Error ->
+ couch_log:debug("Authentication method is not supported: ~p",
element(2,Error)),
+ {not_authenticated, ""}
+ end.
+
+keystone_auth() ->
+ Method = post,
+ URL = config:get("swift", "auth_url"),
+ Header = [{"Content-Type", "application/json"}],
+ Tenant = config:get("swift", "account_tenant"),
+ User = config:get("swift", "username"),
+ Psw = config:get("swift", "password"),
+ Body = "{\"auth\": {\"tenantName\": \"" ++ Tenant
+ ++ "\", \"passwordCredentials\": {\"username\": \""
+ ++ User ++ "\", \"password\": \"" ++ Psw ++ "\"}}}",
--- End diff --
@kxepal It actually depends on the Keystone. I couldn't understand
completely if Keystone permits such passwords or they should be encoded. My
guess Keystone does not permits such passwords , so password will be ascii. Do
you think i should add some encoding here? I can document your comment in the
code, so we can handle it at later stage.
> Store large attachments external to the .couch file
> ---------------------------------------------------
>
> Key: COUCHDB-769
> URL: https://issues.apache.org/jira/browse/COUCHDB-769
> Project: CouchDB
> Issue Type: New Feature
> Components: Database Core
> Reporter: Robert Newson
> Assignee: Adam Kocoloski
> Attachments: external_attachments_alpha.patch
>
>
> For attachment-heavy applications storing the attachments in separate files
> significantly eases compaction problems.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)