As a follow up to #1778282: Apache Solr Search Integration environment deleted when rpc.acquia.com is inaccessible, Acquia Search is unavailable after failed connections to rpc.acquia.com. This is because the subscription data is set to the error code, however Acquia Search requires the "derived_key_salt" array key in order to generate the hash for HMAC authentication. Therefore search remains unavailable until the next successful cron run since it cannot authenticate to Acquia's infrastructure.

As a workaround, the Acquia Search module should store the salt in a separate variable so that the hash can still be generated even when the subscription data is invalid. This would allow Acquia Search to continue to work even after connection failures to rpc.acquia.com.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cpliakas’s picture

Status: Active » Needs review
FileSize
4.81 KB

The attached patch fixes the issue by storing the derived key salt in a variable so that it is available even when the subscription data is not.

cpliakas’s picture

Same patch, removed whitespace differences.

cpliakas’s picture

Status: Needs review » Needs work

Marking as "needs work" because this needs an upgrade path. The upgrade as it stands would cause a search outage until cron was run. We also probably shouldn't rely on hook_update_N(), because although it is best practice to use this for update stuff, there shouldn't be any downtime when the code is updated. Based on experience, we cannot rely on people running update.php.

Nick_vh’s picture

Status: Needs work » Needs review
FileSize
4.11 KB

This patch removes the need of an update function and adds a function that fetches the salt key. If someone accidentally removes the variable in the previous patch, it would break horrendously!

Let me know what you think

cpliakas’s picture

Yes, it would. The approach seems solid and fault tolerant, and also avoids the need for a hook_update_N() implementation. Will test and report back.

cpliakas’s picture

Also, I am still unclear at to why we are not storing the derived key as an environment variable directly. I understand hat the salt can change, but the Drupal site cannot pick that up until cron is run anyways. Regenerating the derived key during the heartbeat seems like the best approach as opposed to calculating the same hash repeatedly on every search request.

cpliakas’s picture

Disregard my comments above. That is an implementation detail that doesn't address the immediate problem and can be changed later if necessary.

Nick_vh’s picture

Hmm,

I agree it could be an environment variable but that would be over-enigneering now. Can we sign-off on the current implementation? Would you be comfortable of marking this RTBC? :)

cpliakas’s picture

No, not yet. Posting a revised patch with some modifications. Stay tuned.

cpliakas’s picture

Couple of things, mostly minor...

acquia_search_derived_key_salt($refresh = TRUE); Should just be acquia_search_derived_key_salt(TRUE);

Related, I'm not sure why we need the refresh flag at all. It is a little confusing and adds some unnecessary logic. We could simply add a variable_set() in acquia_search_acquia_subscription_status(), as that hook implementation already has the required subscription data and executes on all the necessary events (i.e. on a heartbeat and when the module is enabled).

if ($subscription && isset($subscription['derived_key_salt'])) { is a minor nitpick, but it can just be if (isset($subscription['derived_key_salt'])) {. isset() will handle this gracefully whether it is an array or an integer.

We can also omit the change to the tests. Even though I added that in the original patch, tests are busted for D7 all together. See #1784990: Revive unit tests for Acquia Search. Selfishly, I don't want to have to re-roll that patch again :-).

Also, It might be helpful to add some detailed documentation to the acquia_search_derived_key_salt() docblock explaining the function and why it is necessary.

Nick_vh’s picture

Status: Needs review » Reviewed & tested by the community

I can settle with a variable_get/set, but I wanted to make sure the logic can be expanded later on. That is why I extracted it out of the previous context.

The refresh could come in handy in an update function or when we decide to change the variable name. But I agree it could happen with the variable directly. So I settle for your patch.

And, lastly, thanks for the doxygen, surely makes things more readable.

Btw, I'd really love a complete drupalcamp/drupalcon session on the use of empty, isset, !$var and all other checks. PHP never convinced me of the certainty of one of those so I prefer to do the most certain thing so I know it would not fail.

cpliakas’s picture

but I wanted to make sure the logic can be expanded later on

Understood, and that is a good goal. What logic are you thinking about that could be expanded?

The refresh could come in handy in an update function or when we decide to change the variable name

Yes, we could. We could also add a "set" function if necessary, too. I honestly don't see us changing the variable name, though.

Btw, I'd really love a complete drupalcamp/drupalcon session on the use of empty, isset, !$var and all other checks.

That's actually a really cool idea. The simple breakdown is that !$var and empty() will evaluate to the same thing. The difference is that it $var is undefined then !$var will throw a warning error where as empty($var) will not. The following strings are empty() (or will evaluate to FALSE with !$var)

  • "" (an empty string)
  • 0 (0 as an integer)
  • 0.0 (0 as a float)
  • "0" (0 as a string)
  • NULL
  • FALSE
  • array() (an empty array)
  • $var; (a variable declared, but without a value)

isset() evaluates differently, in that it will return TRUE for everything but FALSE, NULL, and undefined variables. Like empty, it will not throw notices if the variable passed to it is undefined.

There are conflicting reports on this, but all three methods have roughly the same performance.

Nick_vh’s picture

If we ever wanted to have separate salts per environment, it could be easier with the function, as you also have in your patch to expand that function.

Committed the follow up of your patch as I think it is certainly robust enough

Nick_vh’s picture

Project: Acquia Connector » Acquia Search
Version: 7.x-2.x-dev » 6.x-3.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Moving to Acquia search

Nick_vh’s picture

Status: Patch (to be ported) » Needs review
FileSize
3.89 KB
Nick_vh’s picture

Status: Needs review » Fixed

manually tested and works as mentioned. No specific drupal code had to be ported

Nick_vh’s picture

Version: 6.x-3.x-dev » 6.x-1.x-dev
Status: Fixed » Patch (to be ported)

needs backport to 6.x-1.x

pwolanin’s picture

Need to add an if statement around the variable_set() - don't set the salt if it's unchanged

pwolanin’s picture

Version: 6.x-1.x-dev » 6.x-3.x-dev
pwolanin’s picture

Status: Patch (to be ported) » Needs review
FileSize
814 bytes
pwolanin’s picture

FileSize
870 bytes

Same patch for the 7.x connector version

pwolanin’s picture

Version: 6.x-3.x-dev » 6.x-1.x-dev
Status: Needs review » Patch (to be ported)

committed to 6.x-3.x and 7.x-2.x connector

Nick_vh’s picture

Status: Patch (to be ported) » Needs review
FileSize
5.14 KB
Nick_vh’s picture

FileSize
4.08 KB

Merged a patch in this patch - cleaning that up :)

Nick_vh’s picture

Status: Needs review » Fixed

reviewed, tested and committed

pwolanin’s picture

There seems like some duplicated code there?

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.