Re: Why is AssetPathConverter not called for javascript stacks

2013-05-23 Thread Bård Magnus Kvalheim
Hi guys.

Sorry for keep asking for this, but I've still got no good solution for it.
Would like to serve stack javascript assets from cdn.

I think I'll try to patch tapestry internals, but would like to know if you
have pointers to where the best place would be.

I'm looking at JavaScriptStackPathConstructorImpl#combinedStackURL as
possible place to call AssetPathConverter.
Could possibly advice it and modify it's return value?

Or possibly higher up in JavaScriptSupportImpl#addAssetsFromStack


Let me know if you have thoughts.

Thanks
Magnus


On Wed, Nov 7, 2012 at 4:48 PM, Bård Magnus Kvalheim mag...@kvalheim.euwrote:

 I'm still searching for a way to resolve this - now in 5.3.6.

 Anyone have ideas on what potentially could be done? Creative ideas
 welcome :)

 cheers
 Magnus


 On Thu, Oct 25, 2012 at 2:13 PM, Bård Magnus Kvalheim 
 mag...@kvalheim.euwrote:


 Regarding AssetPathConverter - should I open a JIRA for stack assets?

 I just created Jira.
 https://issues.apache.org/jira/browse/TAP5-2019

 Let me know if you know of a workaround in tap 5.3.4.

 thanks
 Magnus





Re: Why is AssetPathConverter not called for javascript stacks

2013-05-23 Thread Lance Java
I think the easiest way would be to decorate the JavaScriptStackSource
service. Wrap the default implementation with a version which decorates
getStack(String name) to return a custom JavaScriptStack implementation.

The custom JavaScriptStack will provide wrappers for:
ListAsset getJavaScriptLibraries();
ListStylesheetLink getStylesheets();

You'll need to delegate to AssetPathConverter  in Asset.toClientURL() and
StylesheetLink.getURL()

Lots of wrapping but it looks like it's doable.


Re: Why is AssetPathConverter not called for javascript stacks

2013-05-23 Thread Bård Magnus Kvalheim
Hi.
On Thu, May 23, 2013 at 11:31 AM, Lance Java lance.j...@googlemail.comwrote:

 I think the easiest way would be to decorate the JavaScriptStackSource
 service. Wrap the default implementation with a version which decorates
 getStack(String name) to return a custom JavaScriptStack implementation.

 The custom JavaScriptStack will provide wrappers for:
 ListAsset getJavaScriptLibraries();
 ListStylesheetLink getStylesheets();

 You'll need to delegate to AssetPathConverter  in Asset.toClientURL() and
 StylesheetLink.getURL()


Was thinking about this and as far as I can see with this approach I would
then get 'cdn' urls for the different scripts that make up the stack, and
not the stack url itself - but could be wrong.

I did try to implement my own proposed solution with Advice - quite simple
and it seems to be working fine. Although there could be side-effects I'm
not aware of yet ...

*@Advise(serviceInterface = JavaScriptStackPathConstructor.class)*
*public static void adviseJavaScriptStackPathConstructor(*
* MethodAdviceReceiver receiver,*
* @Local final AssetPathConverter assetPathConverter) {*
*try {*
*  MethodAdvice ma = new MethodAdvice(){*
*  @Override*
*  public void advise(MethodInvocation invocation) {*
*  invocation.proceed();*
*  ListString paths = (ListString) invocation.getReturnValue();*
*  if(paths==null) return;*
*  *
*  ListString newList = new ArrayList(paths.size());*
*  for (String path : paths) {*
*  newList.add(assetPathConverter.convertAssetPath(path));*
*  }*
*  invocation.setReturnValue(newList);*
*  }*
*  };**   *
*  Class? serviceInterface = receiver.getInterface();*
*  
receiver.adviseMethod(serviceInterface.getMethod(constructPathsForJavaScriptStack,
String.class), ma);**   *
*  } catch (Exception e) {*
*  throw new RuntimeException(Can't find methods. Changed API?, e);*
*  }*
*}*

Let me know if you have further suggestions/ideas.

thanks
Magnus


Re: Why is AssetPathConverter not called for javascript stacks

2013-05-23 Thread Lance Java
 I would then get 'cdn' urls for the different scripts that make up the
stack, and not the stack url itself

Oops, I think you're right



 I did try to implement my own proposed solution with Advice

That's a lot of messy byte code manipulation for a single method interface.
I'm a bit old fashioned when it comes to using byte code manipulation. You
can also solve this with a simple delegate.

public static JavaScriptStackPathConstructor
decorateJavaScriptStackPathConstructor(

   JavaScriptStackPathConstructor delegate,

   final AssetPathConverter assetPathConverter)

{

   return new JavaScriptStackPathConstructor {

  public ListString constructPathsForJavaScriptStack(String
stackName) {

 ListString newList = new ArrayListString(paths.size());

 for (String path :
delegate.constructPathsForJavaScriptStack(stackName)) {
new list. add(assetPathConverter.convertAssetPath(path));
 }

  }
   };
}


Re: Why is AssetPathConverter not called for javascript stacks

2013-05-23 Thread Bård Magnus Kvalheim
 I did try to implement my own proposed solution with Advice


 That's a lot of messy byte code manipulation for a single method interface.


Yes, I have to agree. Delegate is probably a better choice in this case.
Cleaner and also typesafe.

Tried your suggestion - and it works just as well as the advice.

Thanks - I'm quite happy with that solution and will update the Jira with
the workaround as well.

cheers
Magnus


Re: Why is AssetPathConverter not called for javascript stacks

2012-11-07 Thread Bård Magnus Kvalheim
I'm still searching for a way to resolve this - now in 5.3.6.

Anyone have ideas on what potentially could be done? Creative ideas welcome
:)

cheers
Magnus


On Thu, Oct 25, 2012 at 2:13 PM, Bård Magnus Kvalheim mag...@kvalheim.euwrote:


 Regarding AssetPathConverter - should I open a JIRA for stack assets?

 I just created Jira.
 https://issues.apache.org/jira/browse/TAP5-2019

 Let me know if you know of a workaround in tap 5.3.4.

 thanks
 Magnus



Re: Why is AssetPathConverter not called for javascript stacks

2012-10-25 Thread Bård Magnus Kvalheim
 Regarding AssetPathConverter - should I open a JIRA for stack assets?

 I just created Jira.
https://issues.apache.org/jira/browse/TAP5-2019

Let me know if you know of a workaround in tap 5.3.4.

thanks
Magnus


Re: Why is AssetPathConverter not called for javascript stacks

2012-10-06 Thread Magnus Kvalheim
On Fri, Oct 5, 2012 at 6:28 PM, Howard Lewis Ship hls...@gmail.com wrote:

 Sounds nice; that's how I've always assumed CDNs worked (lazily)
 though I'm told other require an explicit load of assets into the CDN,
 which is tricky in the Tapestry world where many of those assets are
 dynamically generated (or compiled, or aggregated).


Yes, it works great with dynamic content - although we have to disable cdn
during releases as we currently don't do an atomic update in cluster. If we
didn't then users will be missing assets as we use a cookieless domain for
that. (Expect to do atomic updates soon though.)

Regarding AssetPathConverter - should I open a JIRA for stack assets?


On Fri, Oct 5, 2012 at 10:37 PM, trsvax trs...@gmail.com wrote:

 I wrote a CloudFront CDN while ago and also ran into a few problems. Is
 loading content other than from S3 a new feature?


It's not new - think they started beta back in 2008. However they launch
new features all of the time.


 I wrote a CDNManger
 service that Lazily loaded the assets onto S3. The problem I ran into is
 Tapestry uses the same URL to deliver compressed and uncompressed content
 depending on the client request. I suspect if you just point ClouldFront
 back to your Tapestry app you will have strange problems with old browsers


No, compressed files is supported with cloudfront so it should be a non
issue. It respects the Accept-Encoding header.
http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html

As a cdn, cloudfront is superior to s3. They serve different purposes, but
work well together.
s3 can easily be configured as origin to cloudfront and you pay no
additional cost for this. I'm a satisfied user of both.


Re: Why is AssetPathConverter not called for javascript stacks

2012-10-05 Thread Magnus Kvalheim
Hi Howard - thanks for your reply.

Looks like an oversight.  I'm not familiar with CloudFront; can you
 give me a thumbnail overview of how your CDN hooks work?

 Sure.

Well Cloudfront is at heart a CDN.
It has many features, but how it works is that it delivers content from
edges that are close to end users.
If it don't have the content (or it is expired) it will proxy back to an
'origin' (there can be several) get the content, store it at the edge and
deliver to user.

It is a lazy CDN approach that works well as there is no need to first
upload content to a CDN - like S3.
http://aws.amazon.com/cloudfront/


How it works in the tapestry application is that we have configured a
cookieless domain against the CloudFront with the tapestry app as origin.
It all works great - apart from the stack assets where the
AssetPathConverter#convertAssetPath is never called.

*public class CDNAssetPathConverter implements AssetPathConverter {*
* private IParameter ip;*
* private String applicationVersion;*
*
*
*public CDNAssetPathConverter(@Inject
@Symbol(SymbolConstants.APPLICATION_VERSION) String applicationVersion,*
*@Inject IParameter ip){*
*this.applicationVersion = applicationVersion;*
*this.ip = ip;*
*}*
*String getCDNDomain() {*
*return ip.getString(PKey.DOMAIN_CDN_VERSIONED, null);*
*}*
*@Override*
*public String convertAssetPath(String assetPath) {*
*String domain = getCDNDomain();*
*if(domain==null) return assetPath;*
**
*String result = convertToCDN(assetPath, domain);*
*return result;*
*}*
*private String convertToCDN(String path, String domain) {*
*String _path = path.replaceFirst(^/+, );*
*return String.format(http://%s/%s;, domain, _path);*
*}*
*@Override*
*public boolean isInvariant() {*
*return false;*
*}*
*} *


Re: Why is AssetPathConverter not called for javascript stacks

2012-10-05 Thread Bård Magnus Kvalheim
Hi Howard - thanks for your reply.

Looks like an oversight.  I'm not familiar with CloudFront; can you
 give me a thumbnail overview of how your CDN hooks work?

 Sure.

Well Cloudfront is at heart a CDN.
It has many features, but how it works is that it delivers content from
edges that are close to end users.
If it don't have the content (or it is expired) it will proxy back to an
'origin' (there can be several) get the content, store it at the edge and
deliver to user.

It is a lazy CDN approach that works well as there is no need to first
upload content to a CDN - like S3.
http://aws.amazon.com/cloudfront/


How it works in the tapestry application is that we have configured a
cookieless domain against the CloudFront with the tapestry app as origin.
It all works great - apart from the stack assets where the
AssetPathConverter#convertAssetPath is never called.

*public class CDNAssetPathConverter implements AssetPathConverter {*
* private IParameter ip;*
* private String applicationVersion;*
*
*
*public CDNAssetPathConverter(@Inject
@Symbol(SymbolConstants.APPLICATION_VERSION) String applicationVersion,*
*@Inject IParameter ip){*
*this.applicationVersion = applicationVersion;*
*this.ip = ip;*
*}*
*String getCDNDomain() {*
*return ip.getString(PKey.DOMAIN_CDN_VERSIONED, null);*
*}*
*@Override*
*public String convertAssetPath(String assetPath) {*
*String domain = getCDNDomain();*
*if(domain==null) return assetPath;*
**
*String result = convertToCDN(assetPath, domain);*
*return result;*
*}*
*private String convertToCDN(String path, String domain) {*
*String _path = path.replaceFirst(^/+, );*
*return String.format(http://%s/%s;, domain, _path);*
*}*
*@Override*
*public boolean isInvariant() {*
*return false;*
*}*
*} *


Why is AssetPathConverter not called for javascript stacks

2012-10-04 Thread Bård Magnus Kvalheim
Hi good people.

We were looking into serving assets from aws cloudfront and could quite
easily make a AssetPathConverter to support that thanks to previous
mailinglist discussions and examples.

The only issue now is that stacks (js) don't seem to go through the
AssetPathConverter. Applies to both custom and core stacks.

Tapestry 5.3.4
I've done this in module:
*binder.bind(AssetPathConverter.class,
CDNAssetPathConverter.class).withId(CDNAssetPathConverter);*
*
*
*public static void
contributeServiceOverride(MappedConfigurationClass,Object configuration,*
* @Local AssetPathConverter assetPathConverter) { *
* configuration.add(AssetPathConverter.class, assetPathConverter);*
*}*
*
*
Any idea how to convert paths for javascript stacks?

Many thanks in advance
Magnus Kvalheim


Re: Why is AssetPathConverter not called for javascript stacks

2012-10-04 Thread Howard Lewis Ship
Looks like an oversight.  I'm not familiar with CloudFront; can you
give me a thumbnail overview of how your CDN hooks work?

On Thu, Oct 4, 2012 at 3:54 AM, Bård Magnus Kvalheim mag...@kvalheim.eu wrote:
 Hi good people.

 We were looking into serving assets from aws cloudfront and could quite
 easily make a AssetPathConverter to support that thanks to previous
 mailinglist discussions and examples.

 The only issue now is that stacks (js) don't seem to go through the
 AssetPathConverter. Applies to both custom and core stacks.

 Tapestry 5.3.4
 I've done this in module:
 *binder.bind(AssetPathConverter.class,
 CDNAssetPathConverter.class).withId(CDNAssetPathConverter);*
 *
 *
 *public static void
 contributeServiceOverride(MappedConfigurationClass,Object configuration,*
 * @Local AssetPathConverter assetPathConverter) { *
 * configuration.add(AssetPathConverter.class, assetPathConverter);*
 *}*
 *
 *
 Any idea how to convert paths for javascript stacks?

 Many thanks in advance
 Magnus Kvalheim



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

-
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org