|
|
Tutorial: create, build, publish, deploy
This tutorial walks new users step by step through:
This section assumes that the instructions in installing the SDK have been followed. |
- Creating a new module
- Building a module
- Checking deployment prerequisites
- Deploying a feature
- Undeploying and redeploying modules
- Binding a module
- Configuring a feature
- Activate a service
- Testing the feature
- Adding the feature to the deployment module
Creating a new module
The sdkadm tool includes a command named create-module. For help on using this command, type the following command in the sdkadm tool:
help create-module
create-module uses "module-pack" artifacts as a template for the creation of a new module. Any module-pack can be used to create a new module.
|
|
A module-pack contains one or more modules. The create-module command may create more than one module in the SDK (all in a single directory).
|
The module pack used in this tutorial contains:
-
a group module
-
a SIP POJO feature module
-
a mapper module
-
a profile module.
To view the available module-packs, type the following command inside the sdkadm tool:
list-modules +module-pack
|
|
Where you see a version number of 2.7.0.0 use the version number of the product you have downloaded. |
Now create a new module from the module pack published in opencloud#sentinel-sip-example#sentinel-sip/2.7.0;2.7.0.0. This requires two steps:
1 |
Run the command: create-module my-sip-example opencloud#sentinel-sip-example#sentinel-sip/2.7.0;2.7.0.0 This command:
When prompted, answer as shown in the example output below. Numbered annotations mark the prompts, and their answers are listed by number immediately after the example output. > create-module my-sip-example opencloud#sentinel-sip-example#sentinel-sip/2.7.0;2.7.0.0 downloading https://repo.opencloud.com/artifactory/opencloud-internal-snapshots/opencloud/sentinel-sip/2.7.0/sentinel-sip-example/2.7.0.0/sentinel-sip-example-module-pack-2.7.0.0.zip ... .... (40kB) .. (0kB) [SUCCESSFUL ] opencloud#sentinel-sip-example#sentinel-sip/2.7.0;2.7.0.0!sentinel-sip-example-module-pack.zip(module-pack) (160ms) Extracting '/home/testuser/sentinel-volte-sdk/build/target/ivy-caches/online-resolvers.cache/opencloud/sentinel-sip-example/sentinel-sip/2.7.0/module-packs/sentinel-sip-example-module-pack-2.7.0.0.zip' to '/home/testuser/sentinel-volte-sdk/my-sip-example'. Command line invocation did not contain enough rename arguments to rename all modules. To specify rename arguments on the command line, include <oldvalue>:<newvalue> pairs as additional arguments. Missing values will now be prompted for interactively. Please enter a name for the top level module, usually this will match the name of the directory for the new module Rename top level module 'sentinel-sip-example' to [my-sip-example]:
|
||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 |
Update the As the output says, there are two properties that need updating: The following properties are missing from "deps.properties" and will need to be updated manually: sentinel-sip-support.ivy.revision sentinel-sip-support.ivy.branch Before updating, the cat deps.properties ... edited for brevity fsmtool.ivy.revision=1.1.0.9 sentinel-sip-support.ivy.revision=FIXME_IN_DEPS_PROPERTIES sentinel-registrar.ivy.branch=sentinel-registrar/2.7.0 ... edited for brevity sentinel-registrar-sdk-setup.ivy.branch=sentinel-registrar/2.7.0 sentinel-sip-support.ivy.branch=FIXME_IN_DEPS_PROPERTIES
sentinel-sip-support.ivy.branch=sentinel-sip/2.7.0
sentinel-sip-support.ivy.revision=2.7.0.0 |
||||||||||||||||||
3 |
Add the new module to source control (optional). git add my-sip-example git commit -m "Added initial version of my-sip-example." my-sip-example |
Directory structure
Here’s what your my-sip-example directory should look like:
$ cd my-sip-example/ $ ls build.xml my-sip-example-event-handler-sbbpart feature ivy.xml mapper module.properties profile
It contains these files and directories:
| File or directory | What it’s for |
|---|---|
|
contains build targets so that the module can be built, published, deployed, and so on |
|
provides Ivy with enough information to correctly publish the module |
|
contains variables that are substituted during build and publish |
|
contains a sbbpart module |
|
contains a feature module |
|
contains a mapper module |
|
contains a profile module |
The module.properties file is fairly typical for a group module that publishes a module-pack. Note the three lines indicating where the module pack is created from.
The build.xml and ivy.xml files are also typical for a group module. It’s worth noting that group modules often may publish no artifacts, or only documentation artifacts.
In this case the group module publishes no artifact.
Here’s what the build.xml file looks like:
<?xml version="1.0"?>
<project name="sentinel-sip-example" default="publish-local" basedir=".">
<!-- Common build infrastructure. -->
<property file=".sdk.root"/>
<property file="${sdk.root}/.build.local"/>
<property file="${sdk.root}/.build"/>
<import file="${build}/targets.xml"/>
<target name="do-build">
<default-module-build/>
<default-module-create-artifacts/>
<default-package-module-pack/>
</target>
</project>
Here’s what the ivy.xml file looks like:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="${sdk.ivy.org}"
module="sentinel-sip-example" e:user="${user.name}"
e:indextags="sip, group, example"/>
<configurations>
<conf name="antlib" description="Ant tasks used to build this module" />
<conf name="slee-component" description="SLEE Components published by this module" />
<conf name="api" description="Artifacts needed to compile components using this module" />
<conf name="deploy" description="Deployment artifacts" />
<conf name="doc" description="Documentation source artifacts" />
<conf name="config" description="SLEE component configuration files" />
<conf name="module-pack" description="Module source artifact" />
<conf name="slee-binding" description="SLEE component binding metadata" />
<conf name="provisioning" description="Feature provisioning definitions" />
<conf name="self" description="" visibility="private"/>
<conf name="test" description="" visibility="private"/>
</configurations>
<publications>
<artifact name="${ivy.module}-module-pack" type="module-pack" ext="zip" conf="module-pack"/>
</publications>
<dependencies>
<dependency org="opencloud" name="sentinel-support" rev="${sentinel-support.ivy.revision}" branch="${sentinel-support.ivy.branch}" conf="antlib; self -> api" />
<!-- Add additional features here to have them pulled in by 'ant deploy' -->
<dependency org="${sdk.ivy.org}" name="sentinel-sip-example-feature" rev="latest.${ivy.status}" branch="${branch.name}" conf="slee-component; config; provisioning; slee-binding" />
<dependency org="${sdk.ivy.org}" name="example-pojo-feature-with-multiple-fsms" rev="latest.${ivy.status}" branch="${branch.name}" conf="slee-component; config; slee-binding" />
<dependency org="${sdk.ivy.org}" name="example-feature-event-handler-sbbpart" rev="latest.${ivy.status}" branch="${branch.name}" conf="slee-component; config; slee-binding" />
</dependencies>
</ivy-module>
|
|
This is the original ivy.xml file — it will have different module names than those in your environment.
|
feature
The feature directory is an Ivy module containing a Sentinel POJO feature.
Here’s what it contains:
| File or directory | What it’s for |
|---|---|
|
contains build targets so that the module can be built, published, deployed, and so on |
|
provides Ivy with enough information to correctly build and publish the module |
|
contains variables that are substituted during build and publish |
|
contains a sample configuration for the feature, such as JSLEE profile tables and profiles for the configurer to create |
|
contains documentation source code, in Asciidoc markup format |
|
contains the module’s source code |
build.xml
This build.xml file is typical of any feature (nothing noteworthy to mention):
<?xml version="1.0"?>
<project name="sentinel-sip-example-feature" default="publish-local" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
<!-- Common build infrastructure. -->
<property file=".sdk.root"/>
<property file="${sdk.root}/.build.local"/>
<property file="${sdk.root}/.build"/>
<import file="${build}/targets.xml"/>
<target name="do-build">
<init-extensions/>
<sentinel-annotation-processing/>
<default-module-build/>
<default-module-create-artifacts/>
<default-package-module-pack/>
</target>
</project>
ivy.xml
This ivy.xml file is also typical; however it is very important and so warrants discussion.
It includes module identification-related information, publications, and dependencies.
Here’s more about the info, publications, and dependencies sections in ivy.xml:
|
The 'identification' information is contained in the Here is the
This module’s name is |
||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Next is the publications section, which looks like this:
This feature is a POJO feature. All POJO features publish a single jar file to the JSLEE component jar files can contain many different types of components. POJO features always publish an SBB Part component.
|
||||||||||||
|
Finally the dependencies section for the feature:
The dependencies for the feature include:
The |
The feature includes various Java source files under the src directory. The following is a source listing of the ExamplePojoFeature.java source file.
/**
* Copyright (c) 2014 Open Cloud Limited, a company incorporated in England and Wales (Registration Number 6000941) with its principal place of business at Edinburgh House, St John's Innovation Park, Cowley Road, Cambridge CB4 0DS.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3 The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
*
* 4 The source code may not be used to create, develop, use or distribute software for use on any platform other than the Open Cloud Rhino and Open Cloud Rhino Sentinel platforms or any successor products.
*
* 5 Full license terms may be found https://developer.opencloud.com/devportal/display/OCDEV/Feature+Source+License
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW.
*
* TO THE FULLEST EXTENT PERMISSIBLE BY LAW, THE AUTHOR SHALL NOT BE LIABLE FOR ANY LOSS OF REVENUE, LOSS OF PROFIT, LOSS OF FUTURE BUSINESS, LOSS OF DATA OR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER LOSS OR DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE) MISREPRESENTATION OR OTHERWISE AND REGARDLESS OF WHETHER OPEN CLOUD HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH LOSS OR DAMAGE. THE AUTHORS MAXIMUM AGGREGATE LIABILITY WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, SHALL NOT EXCEED EUR100.
*
* NOTHING IN THIS LICENSE SHALL LIMIT THE LIABILITY OF THE AUTHOR FOR DEATH OR PERSONAL INJURY RESULTING FROM NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION.
*
* Visit Open Cloud Developer's Portal for how-to guides, examples, documentation, forums and more: http://developer.opencloud.com
*/
package com.opencloud.sentinel.example.feature;
import com.opencloud.sce.fsmtool.Facilities;
import com.opencloud.sentinel.annotations.ConfigurationReader;
import com.opencloud.sentinel.annotations.FeatureProvisioning;
import com.opencloud.sentinel.annotations.ProvisioningConfig;
import com.opencloud.sentinel.annotations.ProvisioningField;
import com.opencloud.sentinel.annotations.ProvisioningProfile;
import com.opencloud.sentinel.annotations.ProvisioningProfileId;
import com.opencloud.sentinel.annotations.SentinelFeature;
import com.opencloud.sentinel.common.NullSentinelSessionState;
import com.opencloud.sentinel.feature.ExecutionPhase;
import com.opencloud.sentinel.feature.impl.BaseFeature;
import com.opencloud.sentinel.feature.spi.FeatureEndpoint;
import com.opencloud.sentinel.feature.spi.init.InjectFeatureConfigurationReader;
import com.opencloud.sentinel.feature.spi.init.InjectFeatureStats;
import com.opencloud.slee.annotation.BinderTargets;
import com.opencloud.slee.annotation.SBBPartReference;
import com.opencloud.slee.annotation.SBBPartReferences;
import javax.slee.ActivityContextInterface;
import javax.slee.annotation.ComponentId;
import javax.slee.annotation.ProfileReference;
import javax.slee.annotation.ProfileReferences;
import javax.slee.facilities.Tracer;
/**
*
* An example feature.
*/
@SentinelFeature(
featureName = ExamplePojoFeature.NAME,
componentName = "@component.name@",
featureVendor = "@component.vendor@",
featureVersion = "@component.version@",
featureGroup = SentinelFeature.CORE_FEATURE_GROUP,
configurationReader = @ConfigurationReader(
readerInterface = ExampleConfigReader.class,
readerClass = ExampleConfigProfileReader.class
),
usageStatistics = ExampleUsageStats.class,
executionPhases = ExecutionPhase.SipSessionPhase,
provisioning = @FeatureProvisioning(
displayName = "SIP POJO Feature",
configs = {
@ProvisioningConfig(
type = "SipPojoFeatureConfig",
displayName = "Config",
fields = {
@ProvisioningField(
name = "aValue",
displayName = "A value",
type = "int",
description = "An example value to set."
)
},
profile = @ProvisioningProfile(
tableName = "ExampleConfigProfileTable",
specification = @ProvisioningProfileId(name = "@sentinel-sip-example-profile.name@", vendor = "@sentinel-sip-example-profile.vendor@", version = "@sentinel-sip-example-profile.version@")
)
)
}
)
)
@SBBPartReferences(
sbbPartRefs = {
@SBBPartReference(id = @ComponentId(name = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.name@", vendor = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.vendor@", version = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.version@")),
@SBBPartReference(id = @ComponentId(name = "@sentinel-sip-example-mapper.name@", vendor = "@sentinel-sip-example-mapper.vendor@", version = "@sentinel-sip-example-mapper.version@"))
}
)
@ProfileReferences(
profileRefs = {
@ProfileReference(profile = @ComponentId(name="@sentinel-sip-example-profile.name@", vendor="@sentinel-sip-example-profile.vendor@", version="@sentinel-sip-example-profile.version@"))
}
)
@BinderTargets(services = "sip")
@SuppressWarnings("unused")
public class ExamplePojoFeature extends BaseFeature<NullSentinelSessionState, FeatureEndpoint> implements InjectFeatureConfigurationReader<ExampleConfigReader>, InjectFeatureStats<ExampleUsageStats> {
public ExamplePojoFeature(FeatureEndpoint caller, Facilities facilities, NullSentinelSessionState sessionState) {
super(caller, facilities, sessionState);
}
public static final String NAME = "SipPojoFeature";
@SuppressWarnings("FieldCanBeLocal")
private ExampleConfigReader configReader;
private ExampleUsageStats featureStats;
/**
* All features must have a unique name.
*
* @return the name of this feature
*/
@Override
public String getFeatureName() { return NAME; }
/**
* Kick off the feature.
*
* @param trigger a triggering context. The feature implementation must be able to cast this to a useful type for it to run
* @param activity the slee activity object this feature is related to (may be null)
* @param aci the activity context interface of the slee activity this feature is related to
*/
@Override
public void startFeature(Object trigger, Object activity, ActivityContextInterface aci) {
Tracer tracer = getTracer();
if (tracer.isInfoEnabled()) {
tracer.info("Starting " + NAME);
}
getCaller().featureHasFinished();
featureStats.incrementFeatureStarted(1);
}
public void injectFeatureConfigurationReader(ExampleConfigReader configurationReader) {
this.configReader = configurationReader;
}
/**
* Implement {@link InjectFeatureStats#injectFeatureStats}
*/
@Override
public void injectFeatureStats(ExampleUsageStats featureStats) {
this.featureStats = featureStats;
}
}
|
|
This is the original source file — it may have different package names and feature names than those in your environment. |
sbbpart
The sbbpart directory is an Ivy module containing a Sentinel SbbPart component, in this case defining a simple extension event handler.
Here’s what it contains:
| File or directory | What it’s for |
|---|---|
|
contains build targets so that the module can be built, published, deployed, and so on |
|
provides Ivy with enough information to correctly build and publish the module |
|
contains variables that are substituted during build and publish |
|
contains the module’s source code |
build.xml
The build.xml file is a typical build file (there is nothing specific to describe):
<?xml version="1.0"?>
<project name="example-feature-event-handler-sbbpart" default="publish-local" basedir=".">
<!-- Common build infrastructure. -->
<property file=".sdk.root"/>
<property file="${sdk.root}/.build.local"/>
<property file="${sdk.root}/.build"/>
<import file="${build}/targets.xml"/>
<target name="do-build">
<default-module-build/>
<default-module-create-artifacts/>
</target>
</project>
ivy.xml
The ivy.xml file is typical for an sbbpart that is 'part of' a feature:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="${sdk.ivy.org}"
module="example-feature-event-handler-sbbpart" e:user="${user.name}"
e:indextags="sip, sbb-part">
<description>Example sbb part that demonstrates how to create an event handler that fires an extension event.</description>
</info>
<configurations>
<conf name="antlib" description="Ant tasks used to build this module" />
<conf name="slee-component" description="SLEE Components published by this module" />
<conf name="api" description="Artifacts needed to compile components using this module" />
<conf name="deploy" description="Deployment artifacts" />
<conf name="doc" description="Documentation source artifacts" />
<conf name="config" description="SLEE component configuration files" />
<conf name="module-pack" description="Module source artifact" />
<conf name="slee-binding" description="SLEE component binding metadata" />
<conf name="self" description="" visibility="private"/>
<conf name="test" description="" visibility="private"/>
</configurations>
<publications>
<artifact name="${ivy.module}" type="sbbpart" ext="jar" conf="slee-component, api"/>
<artifact name="${ivy.module}-javadoc" type="javadoc" ext="zip" conf="doc"/>
<artifact name="${ivy.module}-bindings" type="binding" ext="zip" conf="slee-binding"/>
</publications>
<dependencies>
<!-- Common Sentinel build extension and dependencies. -->
<dependency org="opencloud" name="sentinel-sip-support" rev="${sentinel-sip-support.ivy.revision}" branch="${sentinel-sip-support.ivy.branch}" conf="antlib; self -> api" />
<dependency org="opencloud" name="sentinel-http-ra-deploy" rev="${sentinel-http-ra-deploy.ivy.revision}" branch="${sentinel-http-ra-deploy.ivy.branch}" conf="self -> slee-component" />
<dependency org="opencloud" name="http-ratype" rev="${http-ratype.ivy.revision}" branch="${http-ratype.ivy.branch}" conf="api; self -> api" />
<dependency org="javax.inject" name="inject-api" rev="${inject-api.ivy.revision}" conf="self -> api" />
</dependencies>
</ivy-module>
|
|
This is the original source file --- it may have different module names than those in your environment. |
SBB parts are always published as an SBB part component into the slee-component Ivy configuration. A single SBB part component may contain multiple event handler methods.
The sbb part example above is included to show the right file locations, annotations, publications, and dependencies for a typical SIP feature event handler.
Java source
The sbb part includes a single source file under the example-feature-event-handler-sbbpart/src directory.
The sbb part class itself, in the ExampleFeatureEventHandlerSbbPart.java source file:
/**
* Copyright (c) 2014 Open Cloud Limited, a company incorporated in England and Wales (Registration Number 6000941) with its principal place of business at Edinburgh House, St John's Innovation Park, Cowley Road, Cambridge CB4 0DS.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3 The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
*
* 4 The source code may not be used to create, develop, use or distribute software for use on any platform other than the Open Cloud Rhino and Open Cloud Rhino Sentinel platforms or any successor products.
*
* 5 Full license terms may be found https://developer.opencloud.com/devportal/display/OCDEV/Feature+Source+License
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW.
*
* TO THE FULLEST EXTENT PERMISSIBLE BY LAW, THE AUTHOR SHALL NOT BE LIABLE FOR ANY LOSS OF REVENUE, LOSS OF PROFIT, LOSS OF FUTURE BUSINESS, LOSS OF DATA OR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER LOSS OR DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE) MISREPRESENTATION OR OTHERWISE AND REGARDLESS OF WHETHER OPEN CLOUD HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH LOSS OR DAMAGE. THE AUTHORS MAXIMUM AGGREGATE LIABILITY WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, SHALL NOT EXCEED EUR100.
*
* NOTHING IN THIS LICENSE SHALL LIMIT THE LIABILITY OF THE AUTHOR FOR DEATH OR PERSONAL INJURY RESULTING FROM NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION.
*
* Visit Open Cloud Developer's Portal for how-to guides, examples, documentation, forums and more: http://developer.opencloud.com
*/
package com.opencloud.sentinel.example.feature.eventhandler;
import com.opencloud.rhino.facilities.Tracer;
import com.opencloud.rhino.slee.lifecycle.PostCreate;
import com.opencloud.rhino.slee.sbbpart.SbbPartContext;
import com.opencloud.sentinel.common.SentinelFireEventException;
import com.opencloud.sentinel.endpoint.SentinelEndpoint;
import com.opencloud.slee.annotation.du.SBBPartDeployableUnit;
import com.opencloud.slee.annotation.SBBPart;
import com.opencloud.slee.annotation.SBBPartClass;
import com.opencloud.slee.annotation.SBBPartClasses;
import com.opencloud.slee.annotation.SBBPartReference;
import com.opencloud.slee.resources.http.HttpResponse;
import javax.inject.Inject;
import javax.inject.Named;
import javax.slee.ActivityContextInterface;
import javax.slee.CreateException;
import javax.slee.EventContext;
import javax.slee.InitialEventSelector;
import javax.slee.annotation.ComponentId;
import javax.slee.annotation.EventMethod;
import javax.slee.annotation.RATypeBinding;
import javax.slee.annotation.RATypeBindings;
import javax.slee.annotation.SecurityPermissions;
@SBBPart(
id = @ComponentId(name = "@component.name@", vendor = "@component.vendor@", version = "@component.version@"),
sbbPartRefs = {
@SBBPartReference(id = @ComponentId(name = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.name@", vendor = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.vendor@", version = "@sentinel-sip-spi.SentinelSipFeatureSPI SBB Part.version@")),
},
sbbPartClasses = @SBBPartClasses(
sbbPartClass = @SBBPartClass(
className="com.opencloud.sentinel.example.feature.eventhandler.ExampleFeatureEventHandlerSbbPart"
)
)
)
@RATypeBindings(
raTypeBindings = {
@RATypeBinding(
activityContextInterfaceFactoryName = "slee/resources/http/activitycontextinterfacefactory",
resourceAdaptorObjectName = "slee/resources/http/provider",
resourceAdaptorEntityLink = "sentinel-http",
raType = @ComponentId(name = "@sentinel-http-ra-deploy.ResourceAdaptorTypeID.HTTP.name@", vendor = "@sentinel-http-ra-deploy.ResourceAdaptorTypeID.HTTP.vendor@", version = "@sentinel-http-ra-deploy.ResourceAdaptorTypeID.HTTP.version@")
)
}
)
@SBBPartDeployableUnit(
securityPermissions = @SecurityPermissions(securityPermissionSpec = "grant { permission java.security.AllPermission; };")
)
@SuppressWarnings("unused")
public class ExampleFeatureEventHandlerSbbPart {
@PostCreate
public void onCreate() throws CreateException {
if(rootTracer.isFinerEnabled())
rootTracer.finer("SBB part created");
}
public InitialEventSelector ies(InitialEventSelector ies) {
return ies;
}
@EventMethod(
initialEvent = false,
eventType = @ComponentId(name = "@sentinel-http-ra-deploy.EventTypeID.com.opencloud.slee.resources.http.HttpResponse.name@", vendor = "@sentinel-http-ra-deploy.EventTypeID.com.opencloud.slee.resources.http.HttpResponse.vendor@", version = "@sentinel-http-ra-deploy.EventTypeID.com.opencloud.slee.resources.http.HttpResponse.version@")
)
public void onHttpResponse(HttpResponse event, ActivityContextInterface aci, EventContext eventContext) {
if (rootTracer.isFinerEnabled())
rootTracer.finer("ExampleFeatureEventHandlerSbbPart received: " + event);
// see if there is a custom header included that tells me which feature should receive the response
String featureToInvoke = event.getHeader("FeatureToInvoke");
if (null == featureToInvoke || "".equals(featureToInvoke))
featureToInvoke = "TestReceiveHttpResponse";
// processEvent does not return until the event has been processed by Sentinel.
try {
SentinelEndpoint sentinelEndpoint = (SentinelEndpoint)sbbPartContext.getSbbLocalObject();
// ask sentinel to process the http response by calling the 'featureToInvoke' feature
sentinelEndpoint.processEvent(featureToInvoke, event, false, aci, eventContext);
}
catch (NullPointerException | IllegalArgumentException | SentinelFireEventException e) {
rootTracer.fine("Caught exception in processEvent for HttpResponse", e);
}
}
@Inject
private Tracer rootTracer;
@Inject @Named("timer")
private Tracer timerTracer;
@Inject
private SbbPartContext sbbPartContext;
}
|
|
This is the original source file — it may have a different package name than that in your environment. |
mapper
The mapper directory is an Ivy module containing a Sentinel Mapper component.
Here’s what it contains:
| File or directory | What it’s for |
|---|---|
|
contains build targets so that the module can be built, published, deployed, and so on |
|
provides Ivy with enough information to correctly build and publish the module |
|
contains variables that are substituted during build and publish |
|
contains the module’s source code |
build.xml
The build.xml file is a typical build file (there is nothing specific to describe):
<?xml version="1.0"?>
<project name="sentinel-sip-example-mapper" default="publish-local" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
<!-- Common build infrastructure. -->
<property file=".sdk.root"/>
<property file="${sdk.root}/.build.local"/>
<property file="${sdk.root}/.build"/>
<import file="${build}/targets.xml"/>
<target name="do-build">
<default-module-build/>
<default-module-create-artifacts/>
<default-package-module-pack/>
</target>
</project>
ivy.xml
The ivy.xml file is typical for a mapper that is 'part of' a feature:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="${sdk.ivy.org}"
module="sentinel-sip-example-mapper" e:user="${user.name}"
e:indextags="sip, sbb-part, mapper"/>
<configurations>
<conf name="antlib" description="Ant tasks used to build this module" />
<conf name="slee-component" description="SLEE Components published by this module" />
<conf name="api" description="Artifacts needed to compile components using this module" />
<conf name="deploy" description="Deployment artifacts" />
<conf name="doc" description="Documentation source artifacts" />
<conf name="config" description="SLEE component configuration files" />
<conf name="module-pack" description="Module source artifact" />
<conf name="slee-binding" description="SLEE component binding metadata" />
<conf name="provisioning" description="Feature provisioning definitions" />
<conf name="self" description="" visibility="private"/>
<conf name="test" description="" visibility="private"/>
</configurations>
<publications>
<artifact name="${ivy.module}" type="sbbpart" ext="jar" conf="slee-component,api"/>
<artifact name="${ivy.module}-javadoc" type="javadoc" ext="zip" conf="doc"/>
<artifact name="${ivy.module}-bindings" type="binding" ext="zip" conf="slee-binding"/>
</publications>
<dependencies>
<dependency org="opencloud" name="sentinel-sip-support" rev="${sentinel-sip-support.ivy.revision}" branch="${sentinel-sip-support.ivy.branch}" conf="antlib; self -> api" />
</dependencies>
</ivy-module>
|
|
This is the original source file --- it may have different module names than those in your environment. |
Mappers are always published as an SBB part component into the slee-component Ivy configuration. A single SBB part component may contain multiple Sentinel mappers.
Each mapper tends to be small, and many of them tend to be related to one feature or purpose. Therefore a module tends to hold one or more mappers and publish them into a single SBB part.
The mapper example above is included to show the right file locations, annotations, publications, and dependencies for a typical SIP feature mapper.
Java source
The mapper includes two source files, under the mapper/src directory.
First, the package-info.java source file, declaring the mapper as an SBB part component:
/**
* Copyright (c) 2014 Open Cloud Limited, a company incorporated in England and Wales (Registration Number 6000941) with its principal place of business at Edinburgh House, St John's Innovation Park, Cowley Road, Cambridge CB4 0DS.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3 The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
*
* 4 The source code may not be used to create, develop, use or distribute software for use on any platform other than the Open Cloud Rhino and Open Cloud Rhino Sentinel platforms or any successor products.
*
* 5 Full license terms may be found https://developer.opencloud.com/devportal/display/OCDEV/Feature+Source+License
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW.
*
* TO THE FULLEST EXTENT PERMISSIBLE BY LAW, THE AUTHOR SHALL NOT BE LIABLE FOR ANY LOSS OF REVENUE, LOSS OF PROFIT, LOSS OF FUTURE BUSINESS, LOSS OF DATA OR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER LOSS OR DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE) MISREPRESENTATION OR OTHERWISE AND REGARDLESS OF WHETHER OPEN CLOUD HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH LOSS OR DAMAGE. THE AUTHORS MAXIMUM AGGREGATE LIABILITY WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, SHALL NOT EXCEED EUR100.
*
* NOTHING IN THIS LICENSE SHALL LIMIT THE LIABILITY OF THE AUTHOR FOR DEATH OR PERSONAL INJURY RESULTING FROM NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION.
*
* Visit Open Cloud Developer's Portal for how-to guides, examples, documentation, forums and more: http://developer.opencloud.com
*/
/**
<p>Example POJO Feature Mappers</p>
*/
@SBBPart(
id = @ComponentId(name = "@component.name@", vendor = "@component.vendor@", version = "@component.version@")
)
@SBBPartDeployableUnit(
securityPermissions = @SecurityPermissions(securityPermissionSpec = "grant { permission java.security.AllPermission; };")
)
package com.opencloud.sentinel.example.feature;
import javax.slee.annotation.ComponentId;
import javax.slee.annotation.SecurityPermissions;
import com.opencloud.slee.annotation.du.SBBPartDeployableUnit;
import com.opencloud.slee.annotation.SBBPart;
Next, the mapper class itself, in the StringToStringMapper.java source file:
/**
* Copyright (c) 2014 Open Cloud Limited, a company incorporated in England and Wales (Registration Number 6000941) with its principal place of business at Edinburgh House, St John's Innovation Park, Cowley Road, Cambridge CB4 0DS.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3 The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
*
* 4 The source code may not be used to create, develop, use or distribute software for use on any platform other than the Open Cloud Rhino and Open Cloud Rhino Sentinel platforms or any successor products.
*
* 5 Full license terms may be found https://developer.opencloud.com/devportal/display/OCDEV/Feature+Source+License
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW.
*
* TO THE FULLEST EXTENT PERMISSIBLE BY LAW, THE AUTHOR SHALL NOT BE LIABLE FOR ANY LOSS OF REVENUE, LOSS OF PROFIT, LOSS OF FUTURE BUSINESS, LOSS OF DATA OR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER LOSS OR DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE) MISREPRESENTATION OR OTHERWISE AND REGARDLESS OF WHETHER OPEN CLOUD HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH LOSS OR DAMAGE. THE AUTHORS MAXIMUM AGGREGATE LIABILITY WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, SHALL NOT EXCEED EUR100.
*
* NOTHING IN THIS LICENSE SHALL LIMIT THE LIABILITY OF THE AUTHOR FOR DEATH OR PERSONAL INJURY RESULTING FROM NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION.
*
* Visit Open Cloud Developer's Portal for how-to guides, examples, documentation, forums and more: http://developer.opencloud.com
*/
package com.opencloud.sentinel.example.feature;
import com.opencloud.sentinel.annotations.Mapping;
import com.opencloud.sentinel.annotations.SentinelMapper;
import com.opencloud.sentinel.common.NullSentinelSessionState;
import com.opencloud.sentinel.mapper.Mapper;
import com.opencloud.sentinel.mapper.MapperException;
import com.opencloud.sentinel.mapper.MapperFacilities;
/**
* An example mapper.
*/
@SentinelMapper(
mappings = {
@Mapping(name = "StringToString", fromClass = String.class, toClass = String.class)
}
)
@SuppressWarnings("unused")
public class StringToStringMapper implements Mapper<NullSentinelSessionState> {
@Override
public Object map(final Object arg, final NullSentinelSessionState sessionState, final MapperFacilities facilities) throws MapperException {
return arg;
}
}
|
|
These are the original source files — they may have different package names than those in your environment. |
profile
The profile directory is an Ivy module containing a SLEE profile.
Here’s what it contains:
| File or directory | What it’s for |
|---|---|
|
contains build targets so that the module can be built, published, deployed, and so on |
|
provides Ivy with enough information to correctly build and publish the module |
|
contains variables that are substituted during build and publish |
|
contains the module’s source code |
|
|
The build.xml file is a typical build file; there is nothing specific to describe.
|
ivy.xml
Here’s what the profile directory’s ivy.xml file looks like:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="${sdk.ivy.org}"
module="sentinel-sip-example-profile" e:user="${user.name}"
e:indextags="sip, profile"/>
<configurations>
<conf name="antlib" description="Ant tasks used to build this module" />
<conf name="slee-component" description="SLEE Components published by this module" />
<conf name="api" description="Artifacts needed to compile components using this module" />
<conf name="deploy" description="Deployment artifacts" />
<conf name="doc" description="Documentation source artifacts" />
<conf name="config" description="SLEE component configuration files" />
<conf name="module-pack" description="Module source artifact" />
<conf name="slee-binding" description="SLEE component binding metadata" />
<conf name="self" description="" visibility="private"/>
<conf name="test" description="" visibility="private"/>
</configurations>
<publications>
<artifact name="${ivy.module}" type="profile" ext="jar" conf="slee-component,api"/>
<artifact name="${ivy.module}-javadoc" type="javadoc" ext="zip" conf="doc"/>
<artifact name="${ivy.module}-config" type="config" ext="zip" conf="config"/>
<artifact name="${ivy.module}-bindings" type="binding" ext="zip" conf="slee-binding"/>
</publications>
<dependencies>
<dependency org="opencloud" name="sentinel-sip-support" rev="${sentinel-sip-support.ivy.revision}" branch="${sentinel-sip-support.ivy.branch}" conf="antlib; self -> api" />
</dependencies>
</ivy-module>
|
|
This is the original source file — it may have different module names than those in your environment. |
The module publishes a SLEE component jar to the Ivy configurations named slee-component and api.
This SLEE component jar is a JSLEE profile specification jar. Only one JSLEE component can be published into the slee-component Ivy configuration.
The profile module, for a SIP feature, only needs to depend on sentinel-sip-support.
Java source
The profile module includes several source files located under the profile/src directory. The most relevant file is ExampleConfigProfileCMP.java:
/**
* Copyright (c) 2014 Open Cloud Limited, a company incorporated in England and Wales (Registration Number 6000941) with its principal place of business at Edinburgh House, St John's Innovation Park, Cowley Road, Cambridge CB4 0DS.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3 The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
*
* 4 The source code may not be used to create, develop, use or distribute software for use on any platform other than the Open Cloud Rhino and Open Cloud Rhino Sentinel platforms or any successor products.
*
* 5 Full license terms may be found https://developer.opencloud.com/devportal/display/OCDEV/Feature+Source+License
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW.
*
* TO THE FULLEST EXTENT PERMISSIBLE BY LAW, THE AUTHOR SHALL NOT BE LIABLE FOR ANY LOSS OF REVENUE, LOSS OF PROFIT, LOSS OF FUTURE BUSINESS, LOSS OF DATA OR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE OR OTHER LOSS OR DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE, WHETHER ARISING IN CONTRACT, TORT (INCLUDING NEGLIGENCE) MISREPRESENTATION OR OTHERWISE AND REGARDLESS OF WHETHER OPEN CLOUD HAS BEEN ADVISED OF THE POSSIBILITY OF ANY SUCH LOSS OR DAMAGE. THE AUTHORS MAXIMUM AGGREGATE LIABILITY WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, SHALL NOT EXCEED EUR100.
*
* NOTHING IN THIS LICENSE SHALL LIMIT THE LIABILITY OF THE AUTHOR FOR DEATH OR PERSONAL INJURY RESULTING FROM NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION.
*
* Visit Open Cloud Developer's Portal for how-to guides, examples, documentation, forums and more: http://developer.opencloud.com
*/
package com.opencloud.sentinel.example.feature;
import javax.slee.annotation.ComponentId;
import javax.slee.annotation.LibraryReference;
import javax.slee.annotation.Profile;
import javax.slee.annotation.ProfileAbstractClass;
import javax.slee.annotation.ProfileClasses;
import javax.slee.annotation.ProfileLocalInterface;
@Profile(
vendorExtensionID = "@component.name@",
description = "Example Configuration Profile",
id = @ComponentId(name = "@component.name@", vendor = "@component.vendor@", version = "@component.version@"),
libraryRefs = {
@LibraryReference(library = @ComponentId(name = "@sentinel-profile-util-library.name@", vendor = "@sentinel-profile-util-library.vendor@", version = "@sentinel-profile-util-library.version@"))
},
profileClasses = @ProfileClasses(
profileLocal = @ProfileLocalInterface(interfaceName = "com.opencloud.sentinel.example.feature.ExampleConfigProfileLocal"),
profileAbstractClass = @ProfileAbstractClass(className = "com.opencloud.sentinel.example.feature.ExampleConfigProfileAbstractClass")
),
singleProfile = false
)
@SuppressWarnings("unused")
public interface ExampleConfigProfileCMP {
void setAValue(int value);
int getAValue();
}
|
|
This is the original source file — it may have different package names than those in your environment. |
Scoping Feature Configuration
Using the session selection key to select feature config data
|
|
The Sentinel selection key is a simple yet flexible means for scoping feature config data to platform, network, session type, plan, or subscriber granularity. The config data can be stored in SLEE profiles or external databases. Furthermore, the selection key can be modified in order to affect the configuration of subsequent features in the session, including feature script selections (which are also based on the session’s current selection key). |
Below are procedures for accessing the Sentinel selection key; using the SentinelSelectionKeyIterator; and using the selection key to scope SLEE profiles, SLEE tables, and config in external datasources.
Accessing the Sentinel selection key
The selection key is stored in and retrieved from session state:
SentinelSelectionKey key = getSessionState().getSentinelSelectionKey();
The individual fields of the selection key can be accessed directly via getters and setters:
String platformOperator = key.getPlatformOperator();
key.setNetworkOperator("ExampleNet");
All of the fields in the selection key are just Strings, and may contain any valid String value including null. You use the SentinelSelectionKeyIterator when retrieving feature config data.
Using the SentinelSelectionKeyIterator
The SentinelSelectionKeyIterator provides a basic scope fall-back mechanism that can be used to fall-back to the config data for the most specific match of the current session’s selection key.
It does this by returning subkeys of increasingly broader scope from the key provided to it. For example, the following code
SentinelSelectionKey key = getSessionState().getSentinelSelectionKey();
String platform = key.getPlatformOperator();
key.setPlatformOperator("OpenCloud");
key.setNetworkOperator("OpenCloud");
key.setSessionType("call");
key.setPlanId("plan1");
key.setSubscriptionId("64123456789");
SentinelSelectionKeyIterator iter = new SentinelSelectionKeyIterator(key);
while (iter.hasNext()) {
System.out.println(iter.next());
}
…prints the following:
OpenCloud:OpenCloud:call:plan1:64123456789
OpenCloud:OpenCloud:call:plan1:
OpenCloud:OpenCloud:call::
OpenCloud:OpenCloud:::
OpenCloud::::
If one of the fields is null or "", then the subsequent fields will be ignored. In the above example, if the session type field was empty, then only the last two subkeys would be returned.
For example, the following code
SentinelSelectionKey key = getSessionState().getSentinelSelectionKey();
String platform = key.getPlatformOperator();
key.setPlatformOperator("OpenCloud");
key.setNetworkOperator("OpenCloud");
key.setSessionType("");
key.setPlanId("plan1");
key.setSubscriptionId("64123456789");
SentinelSelectionKeyIterator iter = new SentinelSelectionKeyIterator(key);
while (iter.hasNext()) {
System.out.println(iter.next());
}
…prints the following:
OpenCloud:OpenCloud:::
OpenCloud::::
The SentinelSelectionKeyIterator helps to enforce certain assumptions about the state and usage of the selection key. These are:
-
The fields are always populated from left to right.
-
The scope of config data is narrowed progressively by each field from left to right.
-
Once config data is found at a particular scope, config data at broader scopes should be ignored.
Using the selection key to scope SLEE profiles
The most common use for the selection key is to scope profiles. This is commonly achieved by naming the profile after the selection scope to which it applies. The profile name may additionally have a standard prefix or suffix which can be used to further scope the profile.
For example, a feature config table may contain following config profiles:
OpenCloud:OpenCloud:call::
OpenCloud:OpenCloud:::
OpenCloud::::
Then for sessions of type call on the OpenCloud network, the config profile OpenCloud:OpenCloud:call:: would be selected; while for all other session types, the second is chosen.
For the selection key OpenCloud::call::, the config profile OpenCloud:::: would be selected.
For example:
try {
promotionsDbQueryConfigProfileTable =
facilities.getProfileFacility().getProfileTable(PROMOTIONS_DBQUERY_CONFIG_PROFILE_TABLE_NAME);
}
catch (UnrecognizedProfileTableNameException uptne) {
throw new PromotionsDbQueryConfigLoadException("No promotions dbquery config table found:", uptne);
}
// Find the profile whose name is the closest match to the selection key
SentinelSelectionKeyIterator iter = new SentinelSelectionKeyIterator(key);
ProfileLocalObject profile = null;
while (iter.hasNext() && profile == null) {
profile = promotionsDbQueryConfigProfileTable.find(iter.next());
}
if (null == profile)
throw new PromotionsDbQueryConfigLoadException("No promotions dbquery config profile found at any scope for session key: " + key);
Using the selection key to scope SLEE tables
A similar idiom exists for scoping tables as for profiles. However, in the case of scoped tables, a table name prefix or suffix should always be used to avoid saturating the table namespace.
TableExistsVerifier tableExistenceTester = new TableExistsVerifier();
while (iter.hasNext() &&
! tableExistenceTester.profileTableExists(
tableName = (iter.next() + SentinelSelectionKey.SEPARATOR + SUBSCRIBER_DATA_FIELDDEF_PROFILE_TABLE_NAME)));
try {
subscriberDataProfileTable = facilities.getProfileFacility().getProfileTable(tableName);
}
catch (UnrecognizedProfileTableNameException e) {
throw new SubscriberDataLoadException("No subscriber data field definition table exists at any scope for the selection key " + key, e);
}
Using the selection key to scope config in external datasources
You can use the selection key to scope config in external databases, by coding the scope fallback logic in an SQL statement, or by making multiple queries from Java (as in the preceding SLEE examples). It really depends on the interface to the datasource. In any case, the earlier guidelines around selection key semantics should be observed as far as possible.
Propagating properties with the public.properties file
In some cases you may want to propagate certain properties to depending modules, for example component versions.
This is possible with a *.public.properties file published as an additional artifact in the api Ivy configuration.
This file should be named after the Ivy module name with an appended .public.properties, so for example my-sip-example.public.properties.
Once you have created such a file modify the module’s build.xml to process the properties file in any way that is necessary, and then copy it to the target/artifacts directory.
Finally modify the module’s ivy.xml to publish the file in the api configuration:
<publications>
<!-- ... other artifact publications ... --->
<artifact name="${ivy.module}.public" type="properties" ext="properties" conf="api"/>
</publications>
This will make the properties available during the build process of any module that depends on the api configuration of your module.
Building a module
All modules include a build.xml file.
This means that they can be built and published using Ant.
There are two ant target to build and publish a module:
-
publish-local— Compiles and publishes just the current module. Does not include any other modules. -
publish-local-branch— Compiles and publishes all modules, from the current directory and all subdirectories. The module compilation and publication order is automatically determined, such that the modules are compiled and published in the correct order.
If there is ever a question about which to use, publish-local-branch
should take precedence over publish-local.
(The publish-local target can be considered an 'optimisation', where only one module is compiled and published.)
The publish-local-branch target can be run from within any module that includes the availability of the target under the ant -p output.
This means that all modules within a module group can be built (and not other, unnecessary modules). If this target is used from the 'root' of the Sentinel VoLTE Public SDK, then all modules are compiled and published.
There are two 'clean' targets, that delete on-disk files generated by a build. These are:
-
clean— Cleans the current module. This is often used in conjunction withpublish-local. -
clean-branch— Cleans all modules, from the current directory and all subdirectories. This is often used in conjunction withpublish-local-branch.
|
|
As my-sip-example is a module that contains other modules, it makes sense to use publish-local-branch to build it and the contained modules.
|
To compile and publish the my-sip-example module group, use following command:
1 |
|
|---|---|
2 |
Run |
Checking deployment prerequisites
Before you deploy a feature, make sure that the Sentinel services you want are deployed. The installation of Sentinel SIP service is necessary for this example feature. And if the module is bound to a running service, the service must be deactivated.
Check the Sentinel service
To view the currently deployed services, use the following command within the rhino-console tool:
listservices
[Rhino@localhost (#1)] listservices ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=current]
Various types of features are installed into different Sentinel services:
| Type of feature | Name of service deploy module |
|---|---|
Diameter |
|
Registrar |
|
SIP |
|
SS7 Camel |
|
SS7 CS1+ |
|
For Sentinel VoLTE there is one service deploy module: volte-sentinel-public-full-deploy
Deactivate the running service
In order to deactivate the running service, use the rhino-console program and use command deactivateservice in console.
For Example, to deactivate the service name=sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1, type the following command in the console:
deactivateservice name=sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1
For Example, to deactivate the service `name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1`, type the following command in the console: `deactivateservice name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1` [role="small",subs="attributes"] ---- [Rhino@localhost (#0)] listservicesbystate Active Services in Active state on node 101: ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=current] [Rhino@localhost (#1)] deactivateservice name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1 Deactivating service ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1] on node(s) [101] Service transitioned to the Stopping state on node 101 ----
After configuring a feature, the service must be activated again, please see activate a service.
Deploying a feature
Once a module has been published, it can be deployed. To deploy in the Sentinel VoLTE Public SDK, you use the deployer tool.
The deployer reads the current module and looks for its published artifacts. It then uses published artifacts and their dependencies to deploy a module.
|
|
This means that a module must be published before it can be deployed ! |
To deploy my-sip-example:
1 |
|
|---|---|
2 |
Run This command will deploy the current module, after having first deployed any dependent modules. It does so all the way up the dependency heirarchy. If a module has already been deployed into Rhino, and it has the most recent version, then the deployer will skip it. |
|
|
For more about the deployer, please see Deploying modules in Rhino |
Deployer output
Here’s what the deployer’s output should look like:
$ ant -Ddeployer.latest-revision-checks.enabled=false deploy-with-deps
Buildfile: /home/testuser/sentinel-volte-sdk/my-sip-example/build.xml
... edited for brevity ...
init:
init-module:
[echo] Resolving ivy configurations "*" for my-sip-example
deploy-with-deps:
[echo] Deploying module.
[oc:deploy] :: loading settings :: file = /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
[oc:deploy] Created deployer with options: OutdatedIvyModuleDetection: Disabled, IvyStatusesToCheck: [integration]
[oc:deploy] Invoking the deployer to process root module UNSET#my-sip-example#trunk;1.0.0.0-DEV2-testuser and its dependencies ...
[oc:deploy] Installing module UNSET#my-sip-example-event-handler-sbbpart#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] Installing module UNSET#my-sip-example-mapper#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] Installing module UNSET#my-sip-example-profile#trunk;1.0.0.0-DEV3-testuser
[oc:deploy] Installing module UNSET#my-sip-example-feature#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] Deployment Result:
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] | Deploy result:
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] | Modules with no Component:
[oc:deploy] | UNSET#my-sip-example#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] | Deployed Modules:
[oc:deploy] | UNSET#my-sip-example-feature#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] | |__ SbbPartID[name=my-sip-example-feature,vendor=UNSET,version=1.0]
[oc:deploy] | UNSET#my-sip-example-mapper#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] | |__ SbbPartID[name=my-sip-example-mapper,vendor=UNSET,version=1.0]
[oc:deploy] | UNSET#my-sip-example-event-handler-sbbpart#trunk;1.0.0.0-DEV2-testuser
[oc:deploy] | |__ SbbPartID[name=my-sip-example-event-handler-sbbpart,vendor=UNSET,version=1.0]
[oc:deploy] | UNSET#my-sip-example-profile#trunk;1.0.0.0-DEV3-testuser
[oc:deploy] | |__ ProfileSpecificationID[name=my-sip-example-profile,vendor=UNSET,version=1.0]
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] All modules deployed successfully.
[delete] Deleting directory /home/testuser/sentinel-volte-sdk/my-sip-example/target/deployer-work
BUILD SUCCESSFUL
Total time: 9 seconds
The output shows:
-
The deployer analyses the dependencies of the
my-sip-examplemodule. -
The group module depends on the feature module.
-
The deployer analyses the dependencies of the feature module.
It has deployment dependencies on the mapper and profile modules.
These are dependencies on theslee-componentIvy configuration in the feature’sivy.xmlfile. -
The deployer analyses the dependencies of the mapper and profile modules.
These modules have no deployment dependencies, so the deployer installs them into Rhino.
Once the mapper and profile modules have been installed, the feature can be installed, because its dependencies have been deployed. -
The deployer analyses the group module.
This module has published noslee-components, so deployment has finished.
The end of the deployment output shows a summary of what was deployed.
Undeploying and redeploying modules
If code in a module has changed, it makes sense to re-compile and re-publish the module. In order to test changes within Rhino, the module must be deployed. Since a version is already deployed, you’ll want to undeploy it.
The undeploy target is available to remove SLEE components from Rhino. This command works by:
-
calculating which components the module deployed
-
uninstalling those SLEE components from Rhino
|
|
undeploy and deploy-with-deps
The way the
|
For example, the group module my-sip-example has no slee-component publications; so the undeploy target does nothing when executed. However, the profile, mapper, and feature modules it contains do publish SLEE components. And the feature depends on the profile.
Therefore, if you uninstall the profile, you’ll be prompted to confirm that you want to uninstall both the the profile component and the feature component (since it depends on the profile).
But if you uninstall the feature itself, since there are no dependencies on it, only the feature component will be uninstalled.
The undeploy-all target is also available to remove SLEE components from Rhino. This command works by finding all modules in subdirectories of the current working directory, and then asking each module to undeploy.
|
|
If a component has been bound, we recommend unbinding it before undeploying it. |
For more about deployment and undeployment, see Deploying modules in Rhino
Version checks and deployment
When a module is published, its dependencies are published along with it.
With the my-sip-example group, the first time you run publish-local-branch you get this:
| Module | Published revision | Dependency A name and revision | Dependency B name and revision |
|---|---|---|---|
group |
1.0.0-DEV0 |
feature revision 1.0.0-DEV0 |
N/A |
profile |
1.0.0-DEV0 |
N/A |
N/A |
mapper |
1.0.0-DEV0 |
N/A |
N/A |
feature |
1.0.0-DEV0 |
profile revision 1.0.0-DEV0 |
mapper revision 1.0.0-DEV0 |
When the deployer reads the published group module or feature module it will retrieve revision 1.0.0-DEV0, and follow the dependencies to published revision 1.0.0-DEV0 of the appropriate module.
Then, if you rebuilt all modules using the publish-local-branch target, you’d get this:
| Module | Published revision | Dependency A name and revision | Dependency B name and revision |
|---|---|---|---|
group |
1.0.0-DEV1 |
feature revision 1.0.0-DEV1 |
N/A |
profile |
1.0.0-DEV1 |
N/A |
N/A |
mapper |
1.0.0-DEV1 |
N/A |
N/A |
feature |
1.0.0-DEV1 |
profile revision 1.0.0-DEV1 |
mapper revision 1.0.0-DEV1 |
Next, if you’d changed some logic in your profile module, then entered publish-local in the profile module, the revisions would be:
| Module | Published revision | Dependency A name and revision | Dependency B name and revision |
|---|---|---|---|
group |
1.0.0-DEV1 |
feature revision 1.0.0-DEV1 |
N/A |
profile |
1.0.0-DEV2 |
N/A |
N/A |
mapper |
1.0.0-DEV1 |
N/A |
N/A |
feature |
1.0.0-DEV1 |
profile revision 1.0.0-DEV1 |
mapper revision 1.0.0-DEV1 |
When the deployer reads the feature now, it will see that it depends on profile revision 1.0.0-DEV1, not profile revision 1.0.0-DEV2. So it would have to deploy profile revision 1.0.0-DEV1. This would likely to cause confusion, as the changes to the profile would have not taken effect!
This is almost certainly not the desired result (after publishing some changes to the profile).
To avoid this situation, by default the deployer checks that the dependent revision of a module is also the most recently published revision of that module. If those two revisions are not equal, it will not deploy anything into Rhino.
Here’s what the error message looks like:
$ ant deploy-with-deps
Buildfile: /home/testuser/sentinel-volte-sdk/my-sip-example/build.xml
init-build-extensions:
pre-init-ivy-common:
init-ivy-common:
[echo] Ivy Resolvers: /home/testuser/sentinel-volte-sdk/build/ivy/resolvers-remote.xml
[echo] Configuring Ivy with settings: /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
[ivy:var] :: Apache Ivy 2.3.0 - 20130110142753 :: http://ant.apache.org/ivy/ ::
[ivy:var] :: loading settings :: file = /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
ivy-authentication-check:
[ivy:resolve] :: loading settings :: file = /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
[echo] Build infrastructure lib/ directory is up to date.
update-index-properties:
[oc:index-properties] Properties file "/home/testuser/sentinel-volte-sdk/release.properties" already exists.
[oc:index-properties] Index configuration has not changed since previous build.
[oc:index-properties] Index configuration uses dynamic revisions. Current version of indexes will be queried.
[oc:index-properties] Querying current version of: opencloud#volte-sentinel-index#volte/2.7.0;latest.integration
[oc:index-properties] Current version is: opencloud#volte-sentinel-index#volte/2.7.0;2.7.0.0
[oc:index-properties] Currently available index versions are the same as previous build. Properties file "/home/testuser/sentinel-volte-sdk/release.properties" will not be regenerated.
init:
init-module:
[echo] Resolving ivy configurations "*" for my-sip-example
deploy-with-deps:
[echo] Deploying module.
[oc:deploy] :: loading settings :: file = /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
[oc:deploy] Created deployer with options: OutdatedIvyModuleDetection: Enabled, IvyStatusesToCheck: [integration]
[oc:deploy] Invoking the deployer to process root module UNSET#my-sip-example#trunk;1.0.0.0-DEV3-testuser and its dependencies ...
[oc:deploy] Deployment Result:
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] | Deploy result:
[oc:deploy] ---------------------------------------------------------------------
[oc:deploy] | Failed Modules:
[oc:deploy] | UNSET#my-sip-example-profile#trunk;1.0.0.0-DEV4-testuser
[oc:deploy] | |__ Module has a newer revision available in 'latest.integration': '1.0.0.0-DEV5-testuser'.
[oc:deploy] | Note: this failure was encountered while checking that versions are up to date.
[oc:deploy] | To disable this version checking behaviour when running the 'deploy' or 'deploy-with-deps' targets,
[oc:deploy] | set the system property 'deployer.latest-revision-checks.enabled' to 'false'.
[oc:deploy] | E.g. when using Ant:
[oc:deploy] | ant -Ddeployer.latest-revision-checks.enabled=false deploy-with-deps
[oc:deploy] | or within the sdkadm client:
[oc:deploy] | deploy-module ... -properties deployer.latest-revision-checks.enabled=false
[oc:deploy] ---------------------------------------------------------------------
BUILD FAILED
/home/testuser/sentinel-volte-sdk/build/module-targets.xml:88: The following error occurred while executing this line:
/home/testuser/sentinel-volte-sdk/build/toolchain-macrodefs.xml:22: task failed to deploy all modules.
Total time: 8 seconds
To override this behaviour, add the following to the deploy or deploy-with-deps target:
-Ddeployer.latest-revision-checks.enabled=false
For example:
ant -Ddeployer.latest-revision-checks.enabled=false deploy-with-deps
Binding a module
Once the module has been deployed, its SLEE components are present inside the SLEE. However they are not referenced by the appropriate Sentinel service(s).
To have them referenced, they must be bound into the appropriate service(s).
To do this, you use a tool called the binder:
1 |
To invoke the binder, enter the group module (in the example, the ant bind-with-deps This command will read the For the $ ant bind-with-deps
Buildfile: /home/testuser/sentinel-volte-sdk/my-sip-example/build.xml
... edited for brevity ...
bind-with-deps:
[echo] Binding module.
[oc:bind] Connecting to Rhino ...
[oc:bind] Connected to Rhino.
[oc:bind] Initialising Ivy.
[oc:bind] :: loading settings :: file = /home/testuser/sentinel-volte-sdk/build/ivy/ivysettings.xml
[oc:bind] Creating binder.
[oc:bind] Created binder with options: ServiceStrategy: FAIL_IF_ACTIVE
[oc:bind] Finished resolving dependencies.
[oc:bind] Invoking the binder to process root module UNSET#my-sip-example#trunk;1.0.0.0-DEV3-testuser and its dependencies ...
... edited for brevity ...
[oc:bind] Finished processing root modules.
[oc:bind] ---
[oc:bind] | Bind result:
[oc:bind] ---
[oc:bind] | Successfully processed modules:
[oc:bind] | UNSET#my-sip-example-mapper#trunk;1.0.0.0-DEV3-testuser
[oc:bind] | |__ ModuleBindResult{resultParts=[no bindings in module]}
[oc:bind] | UNSET#my-sip-example-feature#trunk;1.0.0.0-DEV3-testuser
[oc:bind] | |__ ModuleBindResult{resultParts=[bindings installed, bindings applied for service ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1]]}
[oc:bind] | UNSET#my-sip-example-profile#trunk;1.0.0.0-DEV4-testuser
[oc:bind] | |__ ModuleBindResult{resultParts=[bindings installed, bindings applied for service ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1]]}
[oc:bind] | UNSET#my-sip-example-event-handler-sbbpart#trunk;1.0.0.0-DEV3-testuser
[oc:bind] | |__ ModuleBindResult{resultParts=[bindings installed, bindings applied for service ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1]]}
[oc:bind] | UNSET#my-sip-example#trunk;1.0.0.0-DEV3-testuser
[oc:bind] | |__ ModuleBindResult{resultParts=[no bindings in module]}
[oc:bind] ---
[oc:bind] ---
[oc:bind] All modules bound successfully.
BUILD SUCCESSFUL
Total time: 24 seconds
When applying bindings, the binder has created a copy of the service and its root SBB, and added a reference from the root SBB to the new feature’s SBB part. |
||
|---|---|---|---|
2 |
In order to see the new service, use the rhino-console program and type [Rhino@localhost (#1)] listservices ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=2.7.0] ServiceID[name=sentinel.registrar,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=current] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0.0-copy#1] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0.0] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=2.7.0] ServiceID[name=volte.sentinel.ss7,vendor=OpenCloud,version=current]
|
||
3 |
Compare a copy with an original using the [Rhino@localhost (#5)] getdescriptor sbb name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0 For component SbbID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0]: Deployable unit: DeployableUnitID[url=file:modules/opencloud/volte-sentinel-sip-service-build-2.7.0.0.jar] Component source: volte-sentinel-sip-sbb.jar Defined using SLEE version: 1.1 Checksum: 0x730f623eb9bce32da00df2bd23243dd5ca310354 Install level: DEPLOYED Manifest attributes: Ant-Version: Apache Ant 1.9.4 Created-By: 1.7.0_71-b14 (Oracle Corporation) Manifest-Version: 1.0 Copies made from this component: SbbID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1] Library refs: LibraryID[name=FSMTool Library,vendor=OpenCloud,version=1.1.0] LibraryID[name=Google Protocol Buffers support runtime,vendor=OpenCloud,version=2.3.0] LibraryID[name=Sentinel promotion script library,vendor=OpenCloud,version=2.7.0] ... edited for brevity ... LibraryID[name=mmtel-standard-schema,vendor=OpenCloud,version=1.0] Event type refs: EventTypeID[name=com.opencloud.slee.resources.http.HttpRequest.GET,vendor=OpenCloud,version=2.2] EventTypeID[name=com.opencloud.slee.resources.http.HttpRequest.POST,vendor=OpenCloud,version=2.2] EventTypeID[name=javax.slee.ActivityEndEvent,vendor=javax.slee,version=1.0] EventTypeID[name=javax.slee.facilities.TimerEvent,vendor=javax.slee,version=1.0] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.ACK,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.BYE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.CANCEL,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.INFO,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.INVITE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.MESSAGE,vendor=jainslee.org,version=1.4] ... edited for brevity ... Profile spec refs: ProfileSpecificationID[name=AddressListEntryProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterMediationConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterMediationOcsConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterSentinelServiceIDConfigProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=ExecutionPoint,vendor=OpenCloud,version=2.7.0] SBB refs: SbbID[name=volte.sentinel.ro.ocs,vendor=OpenCloud,version=2.7.0] SBB part refs: SbbPartID[name=SentinelDiameterMediationMappers,vendor=OpenCloud,version=2.7.0] SbbPartID[name=SentinelRegistrarHssData SBB Part,vendor=OpenCloud,version=2.7.0] SbbPartID[name=SentinelSipFeatureSPI SBB Part,vendor=OpenCloud,version=2.7.0] SbbPartID[name=sentinel-feature-runner,vendor=OpenCloud,version=2.7.0] Resource adaptor type refs: ResourceAdaptorTypeID[name=CDR Generation,vendor=OpenCloud,version=2.2] ResourceAdaptorTypeID[name=Correlation RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=Database Query,vendor=OpenCloud,version=1.4] ResourceAdaptorTypeID[name=Diameter Ro,vendor=jainslee.org,version=2.6] ResourceAdaptorTypeID[name=EasySIP,vendor=jainslee.org,version=1.4] ResourceAdaptorTypeID[name=HTTP,vendor=OpenCloud,version=2.2] ResourceAdaptorTypeID[name=Hector RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=UniqueID RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=sentinel.management.ra.type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=sh-cache-ratype,vendor=OpenCloud,version=1.0.1] Resource adaptor entity links: sentinel-cassandra sentinel-cdrra sentinel-correlation-etcari sentinel-correlation-reorigination sentinel-dbquery sentinel-http sentinel-internal-diameterro sentinel-management sentinel-sip sentinel-uid sh-cache-ra Address profile spec: none This component is a dependent of: BindingDescriptorID[name=my-sip-example-event-handler-sbbpart-volte.sentinel.sip-bindings,vendor=UNSET,version=1.0] BindingDescriptorID[name=mmtel-cdiv-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] BindingDescriptorID[name=mmtel-conf-mapper-library-dialogic-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] BindingDescriptorID[name=mmtel-conf-mapper-library-radisys-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] BindingDescriptorID[name=mmtel-conf-subscription-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] ... edited for brevity ... BindingDescriptorID[name=volte-sip-header-manipulation-feature-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] BindingDescriptorID[name=volte-to-ccr-mappers-volte.sentinel.sip-bindings,vendor=opencloud,version=2.7.0] ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0] ... edited for brevity ...
|
||
4 |
Use the [Rhino@localhost (#7)] getdescriptor sbb name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1 For component SbbID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1]: Copied from: SbbID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0] Copy date: Fri Apr 01 17:26:06 NZDT 2016 Original component: SbbID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0] Install level: VERIFIED Library refs: LibraryID[name=FSMTool Library,vendor=OpenCloud,version=1.1.0] LibraryID[name=Google Protocol Buffers support runtime,vendor=OpenCloud,version=2.3.0] LibraryID[name=Sentinel promotion script library,vendor=OpenCloud,version=2.7.0] LibraryID[name=SentinelAddressList,vendor=OpenCloud,version=2.7.0] LibraryID[name=SentinelFeaturesCommon,vendor=OpenCloud,version=2.7.0] LibraryID[name=SentinelRegistrarHssData,vendor=OpenCloud,version=2.7.0] LibraryID[name=SentinelSdpLibrary,vendor=OpenCloud,version=1.0.0] LibraryID[name=SentinelSs7FeatureSPI,vendor=OpenCloud,version=2.7.0] LibraryID[name=SentinelXpath,vendor=OpenCloud,version=2.7.0] LibraryID[name=easysip-jxpath,vendor=OpenCloud,version=2.7.0] LibraryID[name=jxpath-util,vendor=OpenCloud,version=1.1] LibraryID[name=mmtel-standard-schema,vendor=OpenCloud,version=1.0] Event type refs: EventTypeID[name=com.opencloud.slee.resources.http.HttpRequest.GET,vendor=OpenCloud,version=2.2] EventTypeID[name=com.opencloud.slee.resources.http.HttpRequest.POST,vendor=OpenCloud,version=2.2] EventTypeID[name=javax.slee.ActivityEndEvent,vendor=javax.slee,version=1.0] EventTypeID[name=javax.slee.facilities.TimerEvent,vendor=javax.slee,version=1.0] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.ACK,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.BYE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.CANCEL,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.INFO,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.INVITE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.MESSAGE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.NOTIFY,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.OPTIONS,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.PRACK,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.PUBLISH,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.REFER,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.SUBSCRIBE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipRequest.UPDATE,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipResponse.Error,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipResponse.Provisional,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipResponse.Redirect,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.IncomingSipResponse.Success,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.NoAckReceived,vendor=jainslee.org,version=1.4] EventTypeID[name=org.jainslee.resources.sip.NoPrackReceived,vendor=jainslee.org,version=1.4] Profile spec refs: ProfileSpecificationID[name=AddressListEntryProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterMediationConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterMediationOcsConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=DiameterSentinelServiceIDConfigProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=ExecutionPoint,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=FeatureExecutionScript,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=PromotionsTable,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=SentinelConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=SipSentinelConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=SipThirdPartyCallConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=TccTimerConfigurationProfile,vendor=OpenCloud,version=2.7.0] ProfileSpecificationID[name=registrar.config,vendor=OpenCloud,version=2.7.0] SBB refs: SbbID[name=mmtel-conf-sbb,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=scc-send-request-to-anchor-sbb,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=scc-tads-data-lookup-sbb,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=sentinel-core-subscriber-data-lookup-feature,vendor=OpenCloud,version=2.7.0-copy#2] SbbID[name=volte-hss-subscriber-data-lookup,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=volte-hss-subscriber-data-lookup-2,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=volte-imsid-lookup,vendor=OpenCloud,version=2.7.0-copy#1] SbbID[name=volte.sentinel.ro.ocs,vendor=OpenCloud,version=2.7.0] SBB part refs: SbbPartID[name=SentinelDiameterMediationMappers,vendor=OpenCloud,version=2.7.0] SbbPartID[name=SentinelRegistrarHssData SBB Part,vendor=OpenCloud,version=2.7.0] SbbPartID[name=SentinelSipFeatureSPI SBB Part,vendor=OpenCloud,version=2.7.0] SbbPartID[name=my-sip-example-event-handler-sbbpart,vendor=UNSET,version=1.0-copy#1] ... edited for brevity ... Resource adaptor type refs: ResourceAdaptorTypeID[name=CDR Generation,vendor=OpenCloud,version=2.2] ResourceAdaptorTypeID[name=Correlation RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=Database Query,vendor=OpenCloud,version=1.4] ResourceAdaptorTypeID[name=Diameter Ro,vendor=jainslee.org,version=2.6] ResourceAdaptorTypeID[name=EasySIP,vendor=jainslee.org,version=1.4] ResourceAdaptorTypeID[name=HTTP,vendor=OpenCloud,version=2.2] ResourceAdaptorTypeID[name=Hector RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=UniqueID RA Type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=sentinel.management.ra.type,vendor=OpenCloud,version=2.7.0] ResourceAdaptorTypeID[name=sh-cache-ratype,vendor=OpenCloud,version=1.0.1] Resource adaptor entity links: sentinel-cassandra sentinel-cdrra sentinel-correlation-etcari sentinel-correlation-reorigination sentinel-dbquery sentinel-http sentinel-internal-diameterro sentinel-management sentinel-sip sentinel-uid sh-cache-ra Address profile spec: none This component is a dependent of: ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1]
Both the bindings metadata files and the Rhino bindings files are in JSON format and so can be viewed in a text editor. The bindings metadata files are published in a zip file in the module’s The content of the bindings metadata zip file is created in the module’s |
In order to unbind a module in Rhino, the unbind and unbind-all targets exist.
For more about the binder, please see Binding modules in Rhino .
Configuring a feature
Once a module has been bound it can be configured. Configuration can include:
-
profile tables and profiles
-
RA entity link names
-
RA entity configuration properties
-
RA entity activation state
-
service activation state
-
trace levels for SLEE components.
Configuration is applied through the configure-with-deps target.
This target reads the config Ivy configuration, and walks up the Ivy dependencies configuring components as necessary.
If the configuration in the SLEE matches the desired configuration, the configurer does not apply any changes for that module.
Configuration is specified in a YAML format. An example is included in the my-sip-example/feature/config directory.
For more about configuration, please see Configuring modules in Rhino
Activate a service
If a service was deactivated in checking deployment prerequisites, the service must be activated again.
In order to activate the running service, use the rhino-console program and use activateservice in console.
For Example, to activate the service name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1, type the following command in console:
activateservice name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0-copy#1
[Rhino@localhost (#3)] activateservice name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1 Activating service ServiceID[name=volte.sentinel.sip,vendor=OpenCloud,version=2.7.0.0-copy#1] on node(s) [101] Service transitioned to the Active state on node 101
Testing the feature
For unit testing, include the sentinel-unit-test-support dep in ivy.xml and write unit tests in the tests/directory of the module
Once deployed, bound, and configured, the feature can be integration tested.
After installing your module you may want to make changes and install again. See General Development Cycles for more information.
Adding the feature to the deployment module
In order to be able to easily deploy the feature as part of the deployment
module, you can add a dependency to the ivy.xml in the deployment module so
that the deployment module depends upon the feature module. If the new feature
is a dependency of a group module, then the group module should instead be
added as the dependency to the deployment module’s ivy.xml file.
For the example feature, this means that you would have to add this line to
the dependencies section of the deployment module’s ivy.xml:
<dependency org="${sdk.ivy.org}" name="my-sip-example-feature" rev="latest.${ivy.status}" conf="slee-component; deploy; config; slee-binding" />`
See also Dependencies between module types.
