Showing posts with label GREG. Show all posts
Showing posts with label GREG. Show all posts

Tuesday, December 3, 2013

WSO2 ESB Web-service based remote registry mount

Since WSO2 products are based on Carbon stack, you don't have to store your collections and resources within the same server itself.You can store those across multiple locations.

In this blog post I'm using WSO2 GREG and WSO2 ESB to explain this topic further.

There are multiple methods to mount remote registry in-to the ESB,

1. JDBC based remote configuration
2. Atom based remote configuration
3. Webservice based remote configuration

1st method is the WSO2 recommended approach in production environments as other two methods are not supporting transactions.But there might be scenarios where you can't directly connect to your registry database due to security restrictions.

I'm going to explain the 3rd method further in this blog post.
Before moving forward, lets download and setup Greg and ESB products in my local machine.

1. Start WSO2 Greg by running ./wso2server.sh within <Greg_HOME>/bin directory.

by default all WSO2 products bind to following ports,
HTTPS port  : 9443
HTTP port    : 9763

Since I'm running both products on the same machine for the purpose of writing this blog post I have to start WSO2-ESB with a port offset.

2. Open <ESB_HOME>/repository/conf/carbon.xml and change the offset a,
<Offset>1</Offset>
Lets configure our remote registry instance now, using Webservice configuration.

3. Open <ESB_HOME>/repository/conf/registry.xml and add the following configuration.
<remoteInstance url="https://10.100.0.128:9443/registry">
   <id>instanceid</id>
   <username>admin</username>
   <password>admin</password>
   <type>ws</type>
</remoteInstance>

<mount path="/_system/governance" overwrite="true">
   <instanceId>instanceid</instanceId>
   <targetPath>/_system/governance</targetPath>
</mount>
<mount path="/_system/config" overwrite="true">
   <instanceId>instanceid</instanceId>
   <targetPath>/_system/config</targetPath>
</mount>
Use correct "remoteInstance url" (only have to update the IP address) according to your environment. "instanceid" is the remote registry instance ID(no need to update this value)."username and password" values are to login to the remote registry instance.

In my sample I'm using two mount configurations. "mount path" describes the path where you want to mount. Overwrite variable describes whether you overwrite existing resource or not.It can be any value from true, false, virtual or simply nothing as this parameter is optional. Keep the "instanceId" value as same as in the "id" of remoteInstance configuration above."targetPath" is the path inside remote registry which we are going to mount.

Above configuration I'm going to overwrite both governance and config collections inside ESB from the remote registry collections.

 4. Start WSO2 ESB by running ./wso2server.sh within <ESB_HOME>/bin directory.

Verify the status of WS remote registry mount by,
  i)  Log in to the ESB server's carbon console
  ii) Browse the Registry. Now you should see the config and governance collections(WS remote mounted using my sample registry.xml) are updated with arrow icons.


NOTE-

I en-counted following error while working with WSO2 ESB 4.5.1 and WSO2 GREG 4.5.2, you better try the above sample with latest version of WSO2 Greg and WSO2 ESB.

[2013-12-03 11:42:05,929] ERROR - FIXTransportServiceComponent Error while activating FIX transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.fix.internal.FIXTransportServiceComponent.activate(FIXTransportServiceComponent.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,944] ERROR - JMSTransportServiceComponent Error while activating JMS transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.jms.internal.JMSTransportServiceComponent.activate(JMSTransportServiceComponent.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,952] ERROR - MailTransportServiceComponent Error while activating the mail transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.mail.internal.MailTransportServiceComponent.activate(MailTransportServiceComponent.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
[2013-12-03 11:42:05,960] ERROR - VFSTransportServiceComponent Error while initializing VFS transport management bundle
java.lang.NullPointerException
    at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:89)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.getTransportElement(TransportPersistenceManager.java:127)
    at org.wso2.carbon.core.transports.TransportPersistenceManager.saveTransportConfiguration(TransportPersistenceManager.java:285)
    at org.wso2.carbon.transport.vfs.internal.VFSTransportServiceComponent.activate(VFSTransportServiceComponent.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:252)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
    at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:346)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:588)
    at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:196)
    at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:328)
    at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:221)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:104)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:451)
    at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:513)
    at org.wso2.carbon.core.init.CarbonServerManager.removePendingItem(CarbonServerManager.java:290)
    at org.wso2.carbon.core.init.PreAxis2ConfigItemListener.bundleChanged(PreAxis2ConfigItemListener.java:118)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340) 


You can find out official WSO2 documentation for this topic at [1].


[1] http://docs.wso2.org/display/ESB460/Remote+Registry+Instance+Configuration#RemoteRegistryInstanceConfiguration-WebService-BasedRemoteInstanceConfiguration

Thursday, November 21, 2013

Deploy your own Enterprise Store [part 3]

I will discuss about few UI modifications you can do to make your own Music Store(or whatever) from what you have deployed, using WSO2 ES while following previous blog posts.You can find previous posts from [1] and [2].

At the moment we have our own mp3 asset type plus few other default asset types (gadget, site, e-book) in the ES.


First I'm going to hide all default asset types from the Store UI, there are number of ways to accomplish this task.

1. Get a fresh WSO2-ES pack and remove all default asset rxt's , asset types from store-tenant.json, publisher-tenant.json files while adding our new mp3 asset.

2. By modifying  /_system/config/store/configs/store.json in our registry. You can find this under Resources > Browse > _system > config >store > configs in our management console https://localhost:9443/admin/carbon/admin/login.jsp.

Under content menu you can update store.json with the following content by pressing Edit as text. We are going to remove all default asset types from the config.
{
  "assets": [
    "mp3"
  ],
  "assetsPageSize": 12,
  "commentsPageSize": 10,
  "userSpace": "\/_system\/governance\/users",
  "roles": {
    "Internal\/store": {
      "\/permission\/admin\/login": [
        "ui.execute"
      ]
    }
  },
  "userRoles": [
    "Internal\/store"
  ],
  "permissions": {
    "login": {
      "\/permission\/admin\/login": [
        "ui.execute"
      ]
    }
  },
  "paths": {
    "RXT_EXTENSION_PATH": "\/config\/ext\/"
  }
}
Just save it and browse our store http://localhost:9763/store/



You can update the icon-sprite.png resides under repository/deployment/server/jaggeryapps/store/extensions/assets/mp3/resources/  with a suitable one for our MP3 store.

Without writing a single line of code we can configure our simple digital asset store by using WSO2 ES :)

[1]. http://udarakr.blogspot.com/2013/11/deploy-your-own-enterprise-store-part-1.html
[2]. http://udarakr.blogspot.com/2013/11/deploy-your-own-enterprise-store-part-2.html

Wednesday, November 20, 2013

Deploy your own Enterprise Store [part 2]

I have explained how to install WSO2 ES with bundled default assets in the previous blog post.In this post I will explain how to introduce your own digital asset type to the ES.

Before going though those steps we need to understand a bit about WSO2 Governance Registry. WSO2 GREG enables storing meta-data of our digital assets and assets themselves. You can find more information about WSO2 GREG from here.

Make sure you have WSO2 ES up and running for now,
Browse following URL and sign-in to the management console with the use of given user credentials(default).
Management Console : https://localhost:9443/admin/carbon/admin/login.jsp
Username :admin
Password :admin 
If you browse through following, Main>Resources > Browse> _system> governance > sites > admin > Facebook you will see something similar to the following screen-shot.


This is exactly where all information of Facebook (site-asset) stored. If you select the version 1.0.0 you can see meta-data as well as the properties of this asset.


Lets move to the publisher for a second, browse https://localhost:9443/publisher/asset/site and you will get,


If you compare form fields of add-site form with the properties of above Facebook site-asset, you can clearly understand the relationship between them.

Lets add our own asset type to the ES now. Make sure you proceed with a fresh WSO2 ES pack now on, just unzip already downloaded zip to a different location.

All the resources you need to create are available @ mp3-store git repo.
You can either replace existing files or update as explain in following steps.

1. Introduce meta-data model(rxt file)
If you browse repository/resources/rxts/ directory inside ES distribution, you can see number of .rxt files there. Open site.rxt file using your favorite text editor.

(Yeah !! now you know exactly where all those add-site form fields came from.)

You may create your own meta-data model now.
Create mp3.rxt (Yes im going to create a Music Store) with the following content.
<?xml version="1.0"?>
<artifactType type="application/vnd.wso2-mp3+xml" shortName="mp3" singularLabel="MP3" pluralLabel="MP3s"
              hasNamespace="false" iconSet="10">
    <storagePath>/mp3s/@{overview_provider}/@{overview_name}/@{overview_version}</storagePath>
    <nameAttribute>overview_name</nameAttribute>
    <ui>
        <list>
            <column name="Provider">
                <data type="path" value="overview_provider" href="@{storagePath}"/>
            </column>
            <column name="Name">
                <data type="path" value="overview_name" href="@{storagePath}"/>
            </column>
            <column name="Version">
                <data type="path" value="overview_version" href="@{storagePath}"/>
            </column>
        </list>
    </ui>
    <content>
        <table name="Overview">
            <field type="text" required="true">
                <name>Provider</name>
            </field>
            <field type="text" required="true">
                <name>Name</name>
            </field>
            <field type="text" required="true">
                <name>Version</name>
            </field>
            <field type="text">
                <name>Createdtime</name>
            </field>
        <field type="options">
                <name label="Category">Category</name>
                <values>
                    <value>Country</value>
                    <value>Pop</value>
                    <value>Rock</value>
                </values>
            </field>
        <field type="text" url="true">
                <name>URL</name>
            </field>
        <field type="text" required="true">
                <name>Artists</name>
            </field>
            <field type="text-area">
                <name>Description</name>
            </field>
        </table>
        <table name="Images">
            <field type="text" required="true">
                <name>Thumbnail</name>
            </field>
            <field type="text" required="true">
                <name>Banner</name>
            </field>
        </table>
    </content>

</artifactType>

2. Introduce new asset type to the store.
Go to the repository/deployment/server/jaggeryapps/store/config/ directory inside youe ES distribution.
Open store-tenant.json file and update following line with the new asset type.
"assets": ["gadget", "site", "ebook","mp3"],
3. Go to repository/deployment/server/jaggeryapps/store/extensions/assets directory inside youe ES distribution.
Create a directory called mp3 inside assets directory and copy/paste content from already existing asset type.You can update the content if you wish to do so.

Create mp3.json inside repository/deployment/server/jaggeryapps/store/config/ext/ directory with the following content. You can refer existing default artifact json while creating this.

Sample

{
    "applyTo": "mp3",


    "import": [
        "/modules/rxt/ext/scripts/form.overview.exporter.js",
        "/modules/rxt/ext/scripts/form.exporter.js"],

    "fieldPropertyRules": [
        "overview.name:order=1",
        "overview.provider:order=2",
        "overview.description:order=3",
        "overview.version:order=4"
    ],

    "tables": [

        {
            "name": "*"
        }

    ],

    "fieldProperties": [

        {
            "field": "*",
            "name": "order",
            "value": ""
        },
        {
            "field": "*",
            "name": "hidden",
            "value": "false"
        },
        {
            "field": "*",
            "name": "visible",
            "value": "true"
        },
        {
            "field": "overview.*",
            "name": "save",
            "value": "default"
        },
        {
            "field": "overview.*",
            "name": "editable",
            "value": true
        },
         {
            "field": "images.*",
            "name": "editable",
            "value": true
        },
        {
            "field": "*.lifeCycle",
            "name": "save",
            "value": "asset.lifecycle.action.save"
        },
        {
            "field": "overview.provider",
            "name": "readOnly",
            "value": "true"
        },
         {
            "field":"overview.provider",
            "name":"editable",
            "value":false
        },
         {
            "field":"overview.name",
            "name":"editable",
            "value":false
        },
        {
            "field": "overview.createdtime",
            "name": "hidden",
            "value": "true"
        },
        {
            "field":"overview.version",
            "name":"editable",
            "value":false
        },

    ],

    "fields": [
        {
            "name": "lifeCycle",
            "table": "*",
            "label": "Life Cycle",
            "value": "SampleLifeCycle2"

        } ,
        {
            "name": "banner",
            "table": "images",
            "type": "file"
        },
        {
            "name": "thumbnail",
            "table": "images",
            "type": "file"
        },
        {
            "name": "url",
            "table": "overview",
            "type": "file"
        },
        {
            "name": "description",
            "table": "overview",
            "value": "The provider has not given a description."
        }

    ],

    "permissions": {
        "created": ["Internal/private_{overview_provider}"],
        "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
        "published": ["Internal/private_{overview_provider}"],
        "unpublished": ["Internal/private_{overview_provider}"]
    },


    "storage": {

        "images_banner": {

            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        },

        "images_thumbnail": {

            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        }

    }
}



4.  Introduce new asset type to the publisher.
Go to the  repository/deployment/server/jaggeryapps/publisher/config/ directory inside youe ES distribution.
 Open publisher-tenant.json file and update following line with the new asset type.
"collections": ["gadgets", "sites", "ebooks","mp3s"],


5. Go to the repository/deployment/server/jaggeryapps/publisher/config/ext/ directory inside youe ES distribution. create mp3.json file with the following content.


{
    "applyTo": "mp3",
    "import": [
        "/modules/ext/scripts/rxt.importer.js",
        "/modules/ext/scripts/form.exporter.js"],
    "fieldPropertyRules": [
        "overview.name:order=1",
        "overview.provider:order=2",
        "overview.description:order=3",
        "overview.version:order=4"
    ],
    "tables": [
        {
            "name": "*"
        }
    ],
    "fieldProperties": [
        {
            "field": "*",
            "name": "order",
            "value": ""
        },
        {
            "field": "*",
            "name": "hidden",
            "value": "false"
        },
        {
            "field": "*",
            "name": "visible",
            "value": "true"
        },
        {
            "field": "overview.*",
            "name": "save",
            "value": "default"
        },
        {
            "field": "overview.*",
            "name": "editable",
            "value": true
        },
         {
            "field": "images.*",
            "name": "editable",
            "value": true
        },
        {
            "field": "*.lifeCycle",
            "name": "save",
            "value": "asset.lifecycle.action.save"
        },
        {
            "field": "overview.provider",
            "name": "readOnly",
            "value": "true"
        },
         {
            "field":"overview.provider",
            "name":"editable",
            "value":false
        },
         {
            "field":"overview.name",
            "name":"editable",
            "value":false
        },
        {
            "field": "overview.createdtime",
            "name": "hidden",
            "value": "true"
        },
        {
            "field":"overview.version",
            "name":"editable",
            "value":false
        },

    ],
    "fields": [
        {
            "name": "lifeCycle",
            "table": "*",
            "label": "Life Cycle",
            "value": "SampleLifeCycle2"
        } ,
        {
            "name": "banner",
            "table": "images",
            "type": "file"
        },
        {
            "name": "thumbnail",
            "table": "images",
            "type": "file"
        },
        {
            "name": "url",
            "table": "overview",
            "type": "file"
        },
        {
            "name": "description",
            "table": "overview",
            "value": "The provider has not given a description."
        }
    ],
    "permissions": {
        "created": ["Internal/private_{overview_provider}"],
        "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
        "published": ["Internal/private_{overview_provider}"],
        "unpublished": ["Internal/private_{overview_provider}"]
    },
    "storage": {
        "images_banner": {
            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        },
        "images_thumbnail": {
            "lifecycle": {
                "created": ["Internal/private_{overview_provider}"],
                "in-review": ["Internal/reviewer", "Internal/private_{overview_provider}"],
                "published": ["Internal/everyone", "Internal/private_{overview_provider}", "Internal/reviewer"],
                "unpublished": ["Internal/private_{overview_provider}"]
            }
        }

    }
}
Now you can test the set-up by publishing a mp3.



Start your fresh ES with above changes and browse our mp3 asset type using, https://localhost:9443/publisher/asset/mp3. Yes!! you will get something similar to the following screen-shot.


Just fill those form fields with your own values and create the first mp3 asset on ES :)

You will redirect to a page, where you can see something similar to this.
(Here I'm using the same Thumbnail and Banner created for the CNN site)


You can select your mp3, browse life-cycle and change its state to In-review -> published from created state.( If you do not have permission to run above step just log-in as admin to the ES)


Lets, log-in to the store and browse our newly added asset type using following URL http://localhost:9763/store/assets/mp3


And if you select already published MP3,in my case skyfall :). You will see something similar to the following where you can download, comment and rate the asset.


Now, you are good to go with your own asset (mp3) store.