diff --git a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Author_Group.adoc b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Author_Group.adoc index e69de29bb..4f750db0a 100644 --- a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Author_Group.adoc +++ b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Author_Group.adoc @@ -0,0 +1,6 @@ +[[_author_group]] += Authors + + Amit Bhayani {author-email-amit} + + Grzegorz Figiel ProIDS www.pro-ids.com grzegorz.figiel (at) pro-ids.com \ No newline at end of file diff --git a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Chapter-Graceful_Stop.adoc b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Chapter-Graceful_Stop.adoc new file mode 100644 index 000000000..4c36984e5 --- /dev/null +++ b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Chapter-Graceful_Stop.adoc @@ -0,0 +1,13 @@ +[[_ra_graceful_stop]] += Graceful Stop + +[[_ra_graceful_stop_support]] +== Graceful Stop support + +The RA supports Graceful container stop feature. In Graceful Stop state the RA rejects incoming initial events - it rejects new activities creation. + +[[_ra_graceful_stop_response]] +== Graceful Stop reject support + +When the RA is in Graceful Stopping mode the `TC_ABORT` is send as a response for every new `TC_BEGIN` TCAP message. +`CAP-U-ABORT-REASON: no-reason-given (1)` is used as a u-abort-reason parameter value. diff --git a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Revision_History.adoc b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Revision_History.adoc index f45aaf6a0..264ec3205 100644 --- a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Revision_History.adoc +++ b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/Revision_History.adoc @@ -1,9 +1,15 @@ - -:sectnums!: - -[appendix] -= Revision History - - - + +:sectnums!: + +[appendix] += Revision History + +.Revision History +[cols="1,1,1,1", frame="all", options="header"] +|=== +| Revision number | Date | Author | Description +| 1.0 | 2012-01-21 | Amit Bhayani | Creation of the {this-platform} JAIN SLEE CAP RA User Guide.. +| 1.1 | 2016-09-29 | Grzegorz Figiel | Graceful Stop feature chapter added. +|=== + :sectnums: \ No newline at end of file diff --git a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/User_Guide.adoc b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/User_Guide.adoc index ef9e8648a..7dfe04a2d 100644 --- a/resources/cap/docs/sources-asciidoc/src/main/asciidoc/User_Guide.adoc +++ b/resources/cap/docs/sources-asciidoc/src/main/asciidoc/User_Guide.adoc @@ -1,51 +1,57 @@ -= User Guide to {this-platform} {this-application} {this-ra} RA {project-version} -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:sourcedir: . -:toclevels: 3 -:sectnumlevels: 4 - -:leveloffset: 1 - -include::Book_Info.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Common_Content/Preface.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Chapter-Introduction.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::ra-type/Chapter-Resource_Adaptor_Type.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::ra/Chapter-Resource_Adaptor.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Chapter-Setup.adoc[] - -:leveloffset: 0 - -:leveloffset: 1 - -include::Revision_History.adoc[] - -:leveloffset: 0 += User Guide to {this-platform} {this-application} {this-ra} RA {project-version} +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:sourcedir: . +:toclevels: 3 +:sectnumlevels: 4 + +:leveloffset: 1 + +include::Book_Info.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::Common_Content/Preface.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::Chapter-Introduction.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::ra-type/Chapter-Resource_Adaptor_Type.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::ra/Chapter-Resource_Adaptor.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::Chapter-Setup.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::Chapter-Graceful_Stop.adoc[] + +:leveloffset: 0 + +:leveloffset: 1 + +include::Revision_History.adoc[] + +:leveloffset: 0 diff --git a/resources/cap/docs/sources/src/main/resources/en-US/Author_Group.xml b/resources/cap/docs/sources/src/main/resources/en-US/Author_Group.xml index 9304b23ee..ea498ead2 100644 --- a/resources/cap/docs/sources/src/main/resources/en-US/Author_Group.xml +++ b/resources/cap/docs/sources/src/main/resources/en-US/Author_Group.xml @@ -1,5 +1,8 @@ - %BOOK_ENTITIES; ]> + +%BOOK_ENTITIES; +]> @@ -7,5 +10,11 @@ Bhayani &AUTHOR.EMAIL.AMIT; + + Grzegorz + Figiel + ProIDS www.pro-ids.com + grzegorz.figiel (at) pro-ids.com + diff --git a/resources/cap/docs/sources/src/main/resources/en-US/Chapter-Graceful_Stop.xml b/resources/cap/docs/sources/src/main/resources/en-US/Chapter-Graceful_Stop.xml new file mode 100644 index 000000000..3ae094f7f --- /dev/null +++ b/resources/cap/docs/sources/src/main/resources/en-US/Chapter-Graceful_Stop.xml @@ -0,0 +1,18 @@ + + +%BOOK_ENTITIES; +]> + + Graceful Stop +
+ Graceful Stop support + The RA supports Graceful container stop feature. In Graceful Stop state the RA rejects incoming initial events - it rejects new activities creation. +
+
+ Graceful Stop reject support + When the RA is in Graceful Stopping mode the TC_ABORT is send as a response for every new TC_BEGIN TCAP message. + CAP-U-ABORT-REASON: no-reason-given (1) is used as a u-abort-reason parameter value. + +
+
diff --git a/resources/cap/docs/sources/src/main/resources/en-US/Revision_History.xml b/resources/cap/docs/sources/src/main/resources/en-US/Revision_History.xml index 05a29b47c..abd7d0d69 100644 --- a/resources/cap/docs/sources/src/main/resources/en-US/Revision_History.xml +++ b/resources/cap/docs/sources/src/main/resources/en-US/Revision_History.xml @@ -1,5 +1,8 @@ - %BOOK_ENTITIES; ]> + +%BOOK_ENTITIES; +]> Revision History @@ -18,6 +21,19 @@ + + 1.1 + 2016-09-29 + + Grzegorz + Figiel + + + + Graceful Stop feature chapter added + + + diff --git a/resources/cap/docs/sources/src/main/resources/en-US/User_Guide.xml b/resources/cap/docs/sources/src/main/resources/en-US/User_Guide.xml index 04851431e..4f03aa622 100644 --- a/resources/cap/docs/sources/src/main/resources/en-US/User_Guide.xml +++ b/resources/cap/docs/sources/src/main/resources/en-US/User_Guide.xml @@ -1,30 +1,33 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/resources/cap/ra/pom.xml b/resources/cap/ra/pom.xml index df6fa56b3..3aa778a95 100644 --- a/resources/cap/ra/pom.xml +++ b/resources/cap/ra/pom.xml @@ -1,5 +1,17 @@ 4.0.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + restcomm-slee-ra-cap @@ -9,6 +21,11 @@ restcomm-slee-ra-cap-ra + + + 2.8.0-SNAPSHOT + + ${project.groupId} @@ -20,6 +37,11 @@ javolution ${javolution.version} + + org.mobicents.servers.jainslee.core + spi + ${restcomm.jain.slee.version} + diff --git a/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/CAPResourceAdaptor.java b/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/CAPResourceAdaptor.java index e8d2faf91..030dc47d2 100755 --- a/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/CAPResourceAdaptor.java +++ b/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/CAPResourceAdaptor.java @@ -22,30 +22,7 @@ package org.mobicents.slee.resource.cap; -import javax.naming.InitialContext; -import javax.slee.Address; -import javax.slee.AddressPlan; -import javax.slee.SLEEException; -import javax.slee.facilities.Tracer; -import javax.slee.resource.ActivityAlreadyExistsException; -import javax.slee.resource.ActivityFlags; -import javax.slee.resource.ActivityHandle; -import javax.slee.resource.ActivityIsEndingException; -import javax.slee.resource.ConfigProperties; -import javax.slee.resource.EventFlags; -import javax.slee.resource.FailureReason; -import javax.slee.resource.FireEventException; -import javax.slee.resource.FireableEventType; -import javax.slee.resource.IllegalEventException; -import javax.slee.resource.InvalidConfigurationException; -import javax.slee.resource.Marshaler; -import javax.slee.resource.ReceivableService; -import javax.slee.resource.ResourceAdaptor; -import javax.slee.resource.ResourceAdaptorContext; -import javax.slee.resource.SleeEndpoint; -import javax.slee.resource.StartActivityException; -import javax.slee.resource.UnrecognizedActivityHandleException; - +import org.apache.log4j.Logger; import org.mobicents.protocols.ss7.cap.api.CAPDialog; import org.mobicents.protocols.ss7.cap.api.CAPDialogListener; import org.mobicents.protocols.ss7.cap.api.CAPMessage; @@ -125,6 +102,7 @@ import org.mobicents.protocols.ss7.cap.api.service.sms.ResetTimerSMSRequest; import org.mobicents.protocols.ss7.tcap.asn.comp.PAbortCauseType; import org.mobicents.protocols.ss7.tcap.asn.comp.Problem; +import org.mobicents.slee.container.resource.GracefullyStopableResourceAdaptor; import org.mobicents.slee.resource.cap.events.CAPEvent; import org.mobicents.slee.resource.cap.events.DialogAccept; import org.mobicents.slee.resource.cap.events.DialogClose; @@ -205,15 +183,40 @@ import org.mobicents.slee.resource.cap.wrappers.CAPDialogWrapper; import org.mobicents.slee.resource.cap.wrappers.CAPProviderWrapper; +import javax.naming.InitialContext; +import javax.slee.Address; +import javax.slee.AddressPlan; +import javax.slee.SLEEException; +import javax.slee.facilities.Tracer; +import javax.slee.resource.ActivityAlreadyExistsException; +import javax.slee.resource.ActivityFlags; +import javax.slee.resource.ActivityHandle; +import javax.slee.resource.ActivityIsEndingException; +import javax.slee.resource.ConfigProperties; +import javax.slee.resource.EventFlags; +import javax.slee.resource.FailureReason; +import javax.slee.resource.FireEventException; +import javax.slee.resource.FireableEventType; +import javax.slee.resource.IllegalEventException; +import javax.slee.resource.InvalidConfigurationException; +import javax.slee.resource.Marshaler; +import javax.slee.resource.ReceivableService; +import javax.slee.resource.ResourceAdaptor; +import javax.slee.resource.ResourceAdaptorContext; +import javax.slee.resource.SleeEndpoint; +import javax.slee.resource.StartActivityException; +import javax.slee.resource.UnrecognizedActivityHandleException; + /** * * @author amit bhayani * @author baranowb * @author sergey vetyutnev + * @author ProIDS sp. z o.o. * */ public class CAPResourceAdaptor implements ResourceAdaptor, CAPDialogListener, CAPServiceCircuitSwitchedCallListener, - CAPServiceGprsListener, CAPServiceSmsListener { + CAPServiceGprsListener, CAPServiceSmsListener, GracefullyStopableResourceAdaptor { /** * for all events we are interested in knowing when the event failed to be * processed @@ -247,6 +250,8 @@ public class CAPResourceAdaptor implements ResourceAdaptor, CAPDialogListener, C private String capJndi = null; private transient static final Address address = new Address(AddressPlan.IP, "localhost"); + boolean raIsStopping = false; + public CAPResourceAdaptor() { this.capProvider = new CAPProviderWrapper(this); } @@ -374,6 +379,7 @@ public void raActive() { } catch (Exception e) { this.tracer.severe("Failed to activate CAP RA ", e); } + raIsStopping = false; } public void raConfigurationUpdate(ConfigProperties properties) { @@ -403,9 +409,22 @@ public void raInactive() { this.realProvider.removeCAPDialogListener(this); } - public void raStopping() { - // TODO Auto-generated method stub + /* + * (non-Javadoc) + * @see org.mobicents.slee.container.resource.GracefullyStopableResourceAdaptor#gracefulRaStopping() + */ + public void gracefulRaStopping() { + if (tracer.isFineEnabled()) { + tracer.fine("Graceful stop requested for " + this.resourceAdaptorContext.getEntityName()); + } + raStopping(); + } + public void raStopping() { + if (tracer.isInfoEnabled()) { + tracer.info("raStopping request received for " + this.resourceAdaptorContext.getEntityName()); + } + raIsStopping = true; } public void raUnconfigure() { @@ -520,7 +539,11 @@ private CAPDialogActivityHandle onEvent(String eventName, CAPDialogWrapper dw, C private CAPDialogActivityHandle onEvent(String eventName, CAPDialogWrapper dw, CAPEvent event, int flags) { if (dw == null) { - this.tracer.severe(String.format("Firing %s but CAPDialogWrapper userObject is null", eventName)); + if(!raIsStopping) { + this.tracer.severe(String.format("Skip firing %s as CAPDialogWrapper userObject is null", eventName)); + } else { + this.tracer.fine(String.format("Skip firing %s as CAPDialogWrapper userObject is null, but RA is stopping", eventName)); + } return null; } @@ -591,6 +614,19 @@ private void handleDialogRequest(CAPDialog capDialog, CAPGprsReferenceNumber cap this.tracer.fine(String.format("Received onDialogRequest id=%d ", capDialog.getLocalDialogId())); } + if (raIsStopping) { + this.tracer.warning(String.format(this.resourceAdaptorContext.getEntityName() +" RA is in graceful shutdown mode, dropping new dialog request (otid=%d, dtid=%d)", + capDialog.getRemoteDialogId(), + capDialog.getLocalDialogId())); + try { + capDialog.abort(CAPUserAbortReason.no_reason_given); + } + catch (Exception ex) { + this.tracer.warning("Error while aborting dialog due to raStopping: " + ex.getMessage(), ex); + } + return; + } + CAPDialogActivityHandle activityHandle = new CAPDialogActivityHandle(capDialog.getLocalDialogId()); CAPDialogWrapper capDialogWrapper = null; @@ -630,7 +666,9 @@ public void onDialogRelease(CAPDialog capDialog) { CAPDialogActivityHandle handle = onEvent(dialogRelease.getEventTypeName(), capDialogWrapper, dialogRelease); // End Activity - this.sleeEndpoint.endActivity(handle); + if (handle!=null) { + this.sleeEndpoint.endActivity(handle); + } } catch (Exception e) { this.tracer.severe(String.format( "onDialogRelease : Exception while trying to end activity for CAPDialog=%s", capDialog), e); @@ -706,6 +744,9 @@ public void onCAPMessage(CAPMessage capMessage) { @Override public void onInitialDPRequest(InitialDPRequest ind) { + if (this.tracer.isFineEnabled()) { + this.tracer.fine(String.format("Received onInitialDPRequest id=%d ", ind.getCAPDialog().getLocalDialogId())); + } CAPDialogCircuitSwitchedCallWrapper capDialogCircuitSwitchedCallWrapper = (CAPDialogCircuitSwitchedCallWrapper) ind .getCAPDialog().getUserObject(); InitialDPRequestWrapper event = new InitialDPRequestWrapper(capDialogCircuitSwitchedCallWrapper, ind); diff --git a/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/service/circuitSwitchedCall/wrappers/CAPServiceCircuitSwitchedCallWrapper.java b/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/service/circuitSwitchedCall/wrappers/CAPServiceCircuitSwitchedCallWrapper.java index 3e92532ee..1aabdd392 100644 --- a/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/service/circuitSwitchedCall/wrappers/CAPServiceCircuitSwitchedCallWrapper.java +++ b/resources/cap/ra/src/main/java/org/mobicents/slee/resource/cap/service/circuitSwitchedCall/wrappers/CAPServiceCircuitSwitchedCallWrapper.java @@ -45,7 +45,8 @@ public class CAPServiceCircuitSwitchedCallWrapper implements CAPServiceCircuitSw protected CAPProviderWrapper capProviderWrapper; /** - * @param CAPServiceCircuitSwitchedCall + * @param capProviderWrapper + * @param capServiceCircuitSwitchedCall */ public CAPServiceCircuitSwitchedCallWrapper(CAPProviderWrapper capProviderWrapper, CAPServiceCircuitSwitchedCall capServiceCircuitSwitchedCall) { this.wrappedCircuitSwitchedCall = capServiceCircuitSwitchedCall;