Dynamically registering and unregistering Nancy routes/modules - nancy

We have a situation where our app has a number of modules that implement an api. Each of these modules has a dependency that in turn depends on a data directory path being properly configured. These modules should not even be constructed until this path is configured.
We also have a module that implements the setting and validation of the configuration, including configuring the aforementioned path.
We would like to somehow 'disable' the data modules until such time as the config can be confirmed. The config would be confirmed by, for example, at start up we check that the data directory exists and is valid. Additionally when a user saves changes through the config module we would again do that confirmation. To recap, the user sets the data directory and then the data modules all get enabled. When the user sets an invalid data directory (or we start up and the existing one is invalid) the modules all get disabled.
We tried registering a handler on the pipelines.BeforeRequest but it didn't help. We're actually failing much earlier, when Nancy is instantiating our modules as part of populating a RouteCache. We need to prevent this instantiation until we can confirm we're configured.
It seems like we ought to be able to say "use this set of modules when some condition is true, and use this other set when the condition is false." How does one go about something like this in Nancy?

If all these modules you are referring to implement the same API (i.e. define the same set of Method + Pattern + Action handlers) then perhaps you should use just one module to handle the requests for all of them, and use a capture segment variable (e.g. "/{path}/api/operation/") in your module's pattern to identify which path (i.e. data directory) you are referring to.
Then, in the body of the action, you could check whether the conditions you need are satisfied. Something like this:
Get["/app/{directory}/api/status"] = parameters => {
var dataDirectory = parameters.directory;
// Do whatever condition checks you need with the dataDirectory value
// and return the appropriate HTTP status code if they are not met,
// otherwise continue handling the request
return HttpStatus.OK;
}
Another approach would be (again if using a single module to handle all these requests) to use a custom route parameter constraint (see https://github.com/NancyFx/Nancy/wiki/Defining-routes#custom-constraints).
In this case if your conditions are not met, the route will not be hit at all.

Related

Get Type of Page(PLP or PDP) in SFCC

I want to get the type of the page i.e PLP or PDP page
You can determine the "type" of the page in a couple different ways within SFCC's controllers or backend logic (Server-exectued JavaScript) as well as some other ways when trying to detect this condition in frontend logic. (Browser-executed JavaScript) Additionally, for the frontend and backend solutions it may be different depending on the implementation that you're working on. Depending on it's age, and who implemented it, you may be working in a SiteGenesis, MFRA, or SFRA context. Possibly, even a 100% custom implementation. Therefore please accept this as a very general answer given that the question currently has absolutely no context whatsoever.
Backend Context
In all backend contexts, the solution relies upon the "ClickPath" data store of a session. You must be conscious that this may not be 100% accurate as there could be race conditions wherein users browsing in multiple tabs may have pages visited after the current request is processed and it is unknown whether the last entry in the ClickStream could be 'newer' than the request being processed currently.
Why the pipelineName attribute isn't present on the Request class is a bit confusing to me. Why wouldn't it be? Regardless, we must do what we must do.
SFRA
// in the context of a Controller method
req.session.clickStream.last.pipelineName // returns string like: 'Pipeline-Name'
All other contexts (Site Genesis & MFRA)
// session is a global variable in SFCC. It should be accessible
// in all backend contexts with the exception of certain hook
// contexts.
session.clickStream.last.pipelineName // returns string like: 'Pipeline-Name'
Frontend Context
The frontend context which represents JavaScript running in the browser relies upon variables that have been set by the server within the browser's execution context. Specifically, variables that are accessible within the context of the app.js monolithic module in the case of SiteGenesis or SFRA 'client' modules
SFRA
In SFRA, there's a kind of 'global' JS module which is what you find in main.js and then there are type-specific JS modules like productDetail.js and search.js. In the context of SFRA I'd recommend add your modules/scripts to one of those page-type-specific modules in order to execute different logic based on the page type.
Site Genesis
Within the context of JavaScript executing on the page the following expression will typically give sufficient values to adjust behavior based on page type. Note, you may need to have this expression execute in the context of the closure within app.js in order for it to work.
app.page.type // equals 'product' or 'search' for example (IIRC)

Domain driven design database validation in model layer

I'm creating a design for a Twitter application to practice DDD. My domain model looks like this:
The user and tweet are marked blue to indicate them being a aggregate root. Between the user and the tweet I want a bounded context, each will run in their respective microservice (auth and tweet).
To reference which user has created a tweet, but not run into a self-referencing loop, I have created the UserInfo object. The UserInfo object is created via events when a new user is created. It stores only the information the Tweet microservice will need of the user.
When I create a tweet I only provide the userid and relevant fields to the tweet, with that user id I want to be able to retrieve the UserInfo object, via id reference, to use it in the various child objects, such as Mentions and Poster.
The issue I run into is the persistance, at first glance I thought "Just provide the UserInfo object in the tweet constructor and it's done, all the child aggregates have access to it". But it's a bit harder on the Mention class, since the Mention will contain a dynamic username like so: "#anyuser". To validate if anyuser exists as a UserInfo object I need to query the database. However, I don't know who is mentioned before the tweet's content has been parsed, and that logic resides in the domain model itself and is called as a result of using the tweets constructor. Without this logic, no mentions are extracted so nothing can "yet" be validated.
If I cannot validate it before creating the tweet, because I need the extraction logic, and I cannot use the database repository inside the domain model layer, how can I validate the mentions properly?
Whenever an AR needs to reach out of it's own boundary to gather data there's two main solutions:
You pass in a service to the AR's method which allows it to perform the resolution. The service interface is defined in the domain, but most likely implemented in the infrastructure layer.
e.g. someAr.someMethod(args, someServiceImpl)
Note that if the data is required at construction time you may want to introduce a factory that takes a dependency on the service interface, performs the validation and returns an instance of the AR.
e.g.
tweetFactory = new TweetFactory(new SqlUserInfoLookupService(...));
tweet = tweetFactory.create(...);
You resolve the dependencies in the application layer first, then pass the required data. Note that the application layer could take a dependency onto a domain service in order to perform some reverse resolutions first.
e.g.
If the application layer would like to resolve the UserInfo for all mentions, but can't because it doesn't know how to parse mentions within the text it could always rely on a domain service or value object to perform that task first, then resolve the UserInfo dependencies and provide them to the Tweet AR. Be cautious here not to leak too much logic in the application layer though. If the orchestration logic becomes intertwined with business logic you may want to extract such use case processing logic in a domain service.
Finally, note that any data validated outside the boundary of an AR is always considered stale. The #xyz user could currently exist, but not exist anymore (e.g. deactivated) 1ms after the tweet was sent.

why angularjs core need to detect whether module ngLocale has been created?

In AngularJS source code, there is a section like this, the comment is added by me
try {
angularModule('ngLocale'); //this detect wether ngLocale has been created
} catch (e) {
//if not created , then create it here
angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
}
I understand how ngLocale works, because you can override default ngLocale's $locale service by using files like
<script src="../src/ngLocale/angular-locale_fr-ca.js"></script>
But this after AngularJS core has been run. Because the exception always throw, literally, why not just remove the detection code, and simply use that instead?
angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
The reason for this is because angularjs lacks the ability to check for the availability of a module on a graceful manner. So instead of a checkModule() or findModule(), the framework needs to induce a "module loading exception" for the nonexistent module.
ensure module could accept a parameter to tell the system if it is OK to not find a module, and simply return null as a result.
Actually, letting the module name to start with a question mark in the var mod = angular.module("?moduleName") code path (and not when defining a module) would make it a simple oneliner code to ommit exceptions.

SugarCRM - Prevent record for a customized module

I would like to be able to create a module as an interaction between sugarCRM and an other database. For that I built a module thanks to the module builder tool, and I would like to connect it to a new table which is a join between sugar data and my second app data (to prevent data duplication).
As my new table for the module is a view between two others, sugar views the content without any problem, but throws an exception whenever I try to insert anything. So I would like to use a logic hook who will directly store the data within the two "original" tables.
Here is my problem : even if the data are correctly stored, I would like to prevent sugar to try to store anything. Is there something I can do within my hook to stop sugar action, once my hook finished its job ?
Sorry for my terrible english and thanks for reading.
What I recommend is overriding the Save method in your custom module's controller.
Once you build and deploy the module, there will be a new directory: custom/modules/yourcustommodule. In that directory, create a file named controller.php.
That file should include the following (untested) code:
require_once('include/MVC/Controller/SugarController.php');
class yourcustommoduleController extends SugarController {
function action_save() {
return;
}
}
You could even move your before/after hooks into this custom action function. As long as you don't call the default save method (parent::action_save(); I think), SugarCRM's default save action(s) won't happen.
Important: after deploying a custom module, SugarCRM's best practice is to never redeploy it, but to make all subsequent changes in Studio. This is important because once you make these file-level changes to a custom module, those changes would be lost if you redeploy the module.

Is there a way to determine the loading order of apache modules

I'm developing an Apache based application witch few custom modules.
I'd like to share some functionality in one module with others.
I need to wire them together during stratup phase.
I want to use GetModuleHandle + GetProcAddress (it will rununder Windows only) with a module name - but this will succeed only if the module is already loaded by Apache server.
Is there a way to configure the loading order of Apache modules.
I only need to control my modules - others are irrelevant.
Thank's in advance.
If you're trying to control the Apache hook calling order from the source of your module, you can try using APR_HOOK_FIRST, APR_HOOK_MIDDLE, and APR_HOOK_LAST. Or you can specifically name other modules to enforce ordering constraints. From the docs:
... "There are two mechanisms for doing this. The first, rather crude, method, allows us to specify roughly where the hook is run relative to other modules. The final argument control this. There are three possible values: APR_HOOK_FIRST, APR_HOOK_MIDDLE and APR_HOOK_LAST.
"All modules using any particular value may be run in any order relative to each other, but, of course, all modules using APR_HOOK_FIRST will be run before APR_HOOK_MIDDLE which are before APR_HOOK_LAST. Modules that don't care when they are run should use APR_HOOK_MIDDLE. These values are spaced out, so that positions like APR_HOOK_FIRST-2 are possible to hook slightly earlier than other functions. ...
"The other method allows finer control. When a module knows that it must be run before (or after) some other modules, it can specify them by name. The second (third) argument is a NULL-terminated array of strings consisting of the names of modules that must be run before (after) the current module. For example, suppose we want "mod_xyz.c" and "mod_abc.c" to run before we do, then we'd hook as follows ..." [example follows]

Resources