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

Add ability to pull/push under different goth service accounts. #55

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ config/*credentials.json
.#*
/doc/
.elixir_ls/
.idea/
*.iml
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,40 @@ Diplomat.Query.new(
%{name: "20,000 Leagues Under The Sea"}
) |> Diplomat.Query.execute
```


#### Use multiple accounts with Diplomat
Configure Goth with additional accounts.
```elixir
{:ok, alternative_account} = Jason.decode(File.read!("priv/goth/alternative-account.json"))
Goth.Config.add_config(alternative_account)
```

Require Diplomat and use the with_account option to set current (and only current) process to use alternative process within block.

The account name will be the client_email value from the additional Goth configuration you added by default.

```elixir
require Diplomat
# copy data from prod to stage environment

# 1. Fetch data from production account
prod_entities = Diplomat.with_account(alternative_account["client_email"]) do
Diplomat.Query.new(
"select * from `Book` where name = @name",
%{name: "20,000 Leagues Under The Sea"}
) |> Diplomat.Query.execute
end

# 2. Write to stage/dev account (default environment)
target_project = Diplomat.Client.project()
stage_entities = Enum.map(prod_entities, fn(entity) ->
put_in(entity, [Access.key(:key), Access.key(:project_id)], target_project)
end)
Diplomat.Entity.upsert(stage_entities)
```





17 changes: 17 additions & 0 deletions lib/diplomat.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,21 @@ defmodule Diplomat do
defmodule Proto do
use Protobuf, from: Path.expand("datastore_v1beta3.proto", __DIR__), doc: false
end

defmacro with_account(account, [do: block]) do
account = Macro.expand(account, __ENV__)
quote do
Process.put(:diplomat_account_queue, [unquote(account)] ++ Process.get(:diplomat_account_queue, []))
Process.put(:diplomat_account, unquote(account))
diplomat__response = (unquote(block))
diplomat__account_queue = case Process.get(:diplomat_account_queue, []) do
[_|t] -> t
_ -> []
end
Process.put(:diplomat_account_queue, diplomat__account_queue)
Process.put(:diplomat_account, List.first(diplomat__account_queue))
diplomat__response
end
end

end
16 changes: 13 additions & 3 deletions lib/diplomat/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,26 @@ defmodule Diplomat.Client do

defp token_module, do: Application.get_env(:diplomat, :token_module, Goth.Token)

defp project do
{:ok, project_id} = Goth.Config.get(:project_id)
def diplomat_account() do
Process.get(:diplomat_account)
end

def project do
{:ok, project_id} = case diplomat_account() do
nil -> Goth.Config.get(:project_id)
account -> Goth.Config.get(account, :project_id)
end
project_id
end

defp api_scope, do: api_scope(@api_version)
defp api_scope("v1"), do: "https://www.googleapis.com/auth/datastore"

defp auth_header do
{:ok, token} = token_module().for_scope(api_scope())
{:ok, token} = case diplomat_account() do
nil -> token_module().for_scope(api_scope())
account -> token_module().for_scope({account, api_scope()})
end
{"Authorization", "#{token.type} #{token.token}"}
end

Expand Down
2 changes: 1 addition & 1 deletion lib/diplomat/key.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ defmodule Diplomat.Key do
nil

_ ->
{:ok, global_project_id} = Goth.Config.get(:project_id)
global_project_id = Diplomat.Client.project()

PbPartition.new(
project_id: key.project_id || global_project_id,
Expand Down
4 changes: 2 additions & 2 deletions lib/diplomat/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defmodule Diplomat.Query do

@spec execute(t, String.t() | nil) :: [Entity.t()] | Client.error()
def execute(%__MODULE__{} = q, namespace \\ nil) do
{:ok, project} = Goth.Config.get(:project_id)
project = Diplomat.Client.project()

RunQueryRequest.new(
query_type: {:gql_query, q |> Query.proto()},
Expand All @@ -54,7 +54,7 @@ defmodule Diplomat.Query do

@spec execute_with_pagination(t, String.t() | nil) :: [QueryResultBatch.t()] | Client.error()
def execute_with_pagination(%__MODULE__{} = q, namespace \\ nil) do
{:ok, project} = Goth.Config.get(:project_id)
project = Diplomat.Client.project()

RunQueryRequest.new(
query_type: {:gql_query, q |> Query.proto()},
Expand Down
27 changes: 27 additions & 0 deletions test/diplomat/account_override_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Diplomat.AccountOverrideTest do
use ExUnit.Case
require Diplomat

test "Verify account overrides are applied correctly" do
assert Diplomat.Client.diplomat_account() == nil
r = Diplomat.with_account(:alternative_account_email) do
assert Diplomat.Client.diplomat_account() == :alternative_account_email
a = Diplomat.with_account(:alternative_account2_email) do
assert Diplomat.Client.diplomat_account() == :alternative_account2_email
:alpha
end
assert a == :alpha
assert Diplomat.Client.diplomat_account() == :alternative_account_email
b = Diplomat.with_account(:alternative_account3_email) do
assert Diplomat.Client.diplomat_account() == :alternative_account3_email
:beta
end
assert b == :beta
assert Diplomat.Client.diplomat_account() == :alternative_account_email
:omega
end
assert Diplomat.Client.diplomat_account() == nil
assert r == :omega
end

end