Persist url parameter throughout grails app - groovy

Essentially I am looking to have a url query parameter persist throughout the life of the grails application (POST or GET). ex.
http://localhost:8080/demo/controller/action/?myParam=foobar
I have tried a couple routes. Dynamic method overriding redirect and customizing application tags for createLink. However, since I also use grails webflows it doesn't quite get every single URL. I also tried using a groovy servlet (groovlet) to capture every URL and append the query parameter. The last attempt hasn't been very successful. Am I missing an obvious component to grails? Am I on the right track? Is there another avenue I haven't explored yet?
Thanks in advance

Have you tried using a filter? The following filter will add the param to every request
class MyFilters {
def filters = {
addParam(controller:'*', action:'*') {
before = {
params.myParam = 'foobar'
}
} } }

Related

Why is my dynamic Gatsby page not working

I'm trying to create dynamic pages based on a database that grows by the minute. Therefor it isn't an option to use createPage and build several times a day.
I'm using onCreatePage here to create pages which works fine for my first route, but when I try to make an English route somehow it doesn't work.
gatby-node.js:
exports.onCreatePage = async ({ page, actions: { createPage } }) => {
if (page.path.match(/^\/listing/)) {
page.matchPath = '/listing/:id'
createPage(page)
}
if (page.path.match(/^\/en\/listing/)) {
page.matchPath = '/en/listing/:id'
createPage(page)
}
}
What I'm trying to achieve here is getting 2 dynamic routes like:
localhost:8000/listing/123 (this one works)
localhost:8000/en/listing/123 (this one doesn't work)
My pages folder looks like this:
pages
---listing.tsx
---en/
------listing.tsx
Can anyone see what I'm doing wrong here?
--
P.S. I want to use SSR (available since Gatsby v4) by using the getServerData() in the templates for these pages. Will that work together with pages created dynamically with onCreatePage or is there a better approach?
According to what we've discussed in the comment section: the fact that the /en/ path is never created, hence is not entering the following condition:
if (page.path.match(/^\/en\/listing/)) {
page.matchPath = '/en/listing/:id'
createPage(page)
}
Points me to think that the issue is on your createPages API rather than onCreatePage, which means that your english page is not even created.
Keep in mind that onCreatePage API is a callback called when a page is created, so it's triggered after createPages.
If you add a console.log(page.path) you shouldn't see the English page in the IDE/text editor console so try debugging how are you creating the /en/ route because it seems that onCreatePage doesn't have any problem.

How to add a custom dimension to request telemetry in a Nodejs/typescript azure function?

Goal
A request comes in and is handled by the Azure Functions run-time. By default it creates a Request entry, and a bunch of Trace entries in Application Insights. I want to add a custom dimension to that top level request item (on a per-request basis) so I can use it for filtering/analysis later.
Query for -requests- on Application Insights
Resulting list of requests including custom dimensions column
The Azure Functions runtime adds a few custom dimensions already. I want to add a few of my own.
Approach
The most promising approach I've found is show below (taken from here https://github.com/microsoft/ApplicationInsights-node.js/issues/392)
appInsights.defaultClient.addTelemetryProcessor(( envelope, context ) => {
var data = envelope.data.baseData;
data.properties['mykey'] = 'myvalue';
return true;
});
However, I find that this processor is only called for requests that I initialise within my function. For example, if I make an HTTP request to another service, then details of that request will be passed thru the processor and I can add custom properties to it. But the main function does not seem to pass thru here. So I can't add my custom property.
I also tried this
defaultClient.commonProperties['anotherCustomProp'] = 'bespokeProp2'
Same problem. The custom property doesn't arrive in application insights. I've played with many variations on this and it appears that the logging done by azure-functions is walled off from anything I can do within my code.
The best workaround I have right now, is to call trackRequest manually. This is okay, except I end up with each request logged twice in application insights, one by the framework and one by me. And both need to have the same operation_id otherwise I can't find the associated trace/error items. So I'm having to extract the operationId in a slightly hacky way. This may be fine, my knowledge of application insights is pretty naive at this point.
import { setup, defaultClient } from 'applicationinsights' // i have to import the specific functions, because "import ai from applicationinsights" returns null
// call this because otherwise defaultClient is null.
// Some examples call start(), I've tried with and without this.
// I think the start() function must be useful when you're adding application-insights to a project fresh, whereas I think the azure-functions run-time must be doing this already.
setup()
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
// Extract the operation id from the traceparent as per w3 standard https://www.w3.org/TR/trace-context/.
const operationId = context.traceContext.traceparent.split('-')[1]
var operationIdOverride = { 'ai.operation.id': operationId }
// Create my own trackRequest entry
defaultClient.trackRequest({
name: 'my func name',
url: context.req.url.split('?')[0],
duration: 123,
resultCode: 200,
success: true,
tagOverrides: operationIdOverride,
properties: {
customProp: 'bespokeProp'
}
})
The Dream
Our C# cousins seem to have an array of options, like Activity.Current.tags and the ability to add TelemetryInitializer. However it looks like what I'm trying to do is supported, I'm just not finding the right combination of commands! Is there something similar for javascript/typescript/nodejs, where I can just add a tag on a per-request basis? Along the lines of context.traceContext.attributes['myprop'] = 'myValue'
Alternative
Alternatively, instrumenting my code using my own TelemetryClient (rather than the defaultClient) using trackRequest, trackTrace, trackError etc, is not a very big job and should work well - that would be more explicit. Should I just do that? Is there a way to disable the azure functions tracking - or perhaps I just leave that as something running side-by-side.

Hosting project in IIS appends project name to the URL and breaks my routing

I have a web api 2 project, and in my code I do some routing stuff myself.
I have all my actions going to a single route, so hitting localhost/<anything> will always go to one route.
In that route I am doing some custom pattern matching.
If the user goes to /Kittens/AdoptAKitten/12345
It will match against a template I have using regex, defined as /Kittens/AdoptAKitten/{something}
The problem is when I host my project locally, it ends up at localhost/KITTENCORP.ADOPTION/ which is the name of my project. As a result the route matching doesn't work.
I am not sure how to take into account this 'root' address. Previously I was just looking at the domain part of the Uri object but I need to include this part in the comparison to make it work (or disregard/remove it).
This code will however also be deployed to a server somewhere at which point it will probably be hosted on adoptionservice.kittens.org and thus adoptionservice.kittens.org/Kittens/AdoptAKitten/12345 will be the url. So it has to account for both situations.
Any ideas how I can resolve this problem?
For anyone stumbling across this and wondering the same thing, I fixed it with this code:
// When hosted in IIS it may get a virtual path such as localhost/KittenLibrary that needs including in comparisons
if (!string.IsNullOrEmpty(HttpRuntime.AppDomainAppVirtualPath))
{
urlStart = UrlCombine(urlStart, HttpRuntime.AppDomainAppVirtualPath);
}
UrlCombine is a function I pinched from another SO question:
private static string UrlCombine(string url1, string url2)
{
if (url1.Length == 0)
{
return url2;
}
if (url2.Length == 0)
{
return url1;
}
url1 = url1.TrimEnd('/', '\\');
url2 = url2.TrimStart('/', '\\');
return string.Format("{0}/{1}", url1, url2);
}

symfony2 get firewall name on login page

I'd want to use a login page to access different firewalls, so I need to get information about the firewall I'm logging in.
In my controller I'd use
$this->container->get('security.context')->getToken()->getProviderKey()
but as an anonymous user I don't have access to getProviderKey method.
I could also parse
_security.xxx.target_path
to get xxx firewall but I'm looking for a more general solution if it exists at all.
Any idea?
As of symfony 3.2, you can now get the current firewall configuration using the following:
public function indexAction(Request $request)
{
$firewall = $this->container
->get('security.firewall.map')
->getFirewallConfig($request)
->getName();
}
Ref: http://symfony.com/blog/new-in-symfony-3-2-firewall-config-class-and-profiler
For Symfony 3.4 I wrote this to avoid referencing the non-public "security.firewall.map" service:
$firewallName = null;
if (($firewallContext = trim($request->attributes->get("_firewall_context", null))) && (false !== ($firewallContextNameSplit = strrpos($firewallContext, ".")))) {
$firewallName = substr($firewallContext, $firewallContextNameSplit + 1);
}
(Referencing "security.firewall.map" on 3.4 will throw an exception.)
Edit: This will not work in a custom exception controller function.
I was doing a little research on this myself recently so that I could send this information in an XACML request as part of the environment.
As far as I can tell from GitHub issues like this one:
https://github.com/symfony/symfony/issues/14435
There is currently no way to reliably get the information out of Symfony except the dirty compiler pass hack suggested on the linked issue. It does appear from the conversation on these issues, they are working on making this available, however, the status is still open, so we will have to be patient and wait for it to be provided.
#Adambean's answer is pretty elegant, but I'd write it as a one-liner:
$firewallName = array_slice(explode('.', trim($request->attributes->get('_firewall_context'))), -1)[0];
The difference is that $firewallName will always be a string (which may be empty).
Also, please note that this answer (like #Adambean's) doesn't work for a firewall with a dot in its name.

How can I change Magento theme via query string?

Is it possible to change Magento template via query string?
I am developing a custom template and sometimes I want to check if I broke something, so I want to change via query string the theme for the default one.
I am looing for something like this:
?_theme=default
Does something like this exists?
Programmatically:
You could write an observer that is listening to event <controller_action_predispatch>
The observer method could look like this:
public function changeTheme(){
if (Mage::app()->getRequest()->getParam('layout_switch') == '1'){
Mage::getDesign()->setArea(‘frontend’)
->setPackageName(Mage::app()->getRequest()->getParam('package'))
->setTheme(Mage::app()->getRequest()->getParam('theme'));
}
return;
}
}
Then you would just need to call your page with e.g.
yourdomain.com/index.php/layout_switch/1/package/default/theme/default
The short answer is no you can't (as far as I know)
However if it's your local installation (which you use only as a development enviroment!) you can use a trick:
Create another Store view and assign whatever theme you want to that store view and then access it like yourstore.com/?___store=storecode
as simple as 1-2-3.:) Create a new dev theme and copy all the files from the current live theme to the new one (both app/design and sking). Then observe controller_action_predispatch event and then in the observer function simply:
$controllerAction = $observer->getControllerAction();
if ($controllerAction->getLayout()->getArea() == Mage_Core_Model_App_Area::AREA_FRONTEND) {
$ipAddress = Mage::helper('core/http')->getRemoteAddr();
$ipAddresses = array('xxx.xxx.xxx.xxx');
if (in_array($ipAddress, $ipAddresses)) {
Mage::getDesign()->setTheme('theme-wanted');
}
}
Very helpful for design tweaks indeed. After the work is finished the observer should be disabled or module deactivated until next time

Resources