Indications
===========
Indication is a reaction to some specific event that occurs in response to a
change to a particular change in data. LMIShell can perform a indication
subscription, by which we can receive such event responses.

Subscribing to an indication
----------------------------
The LMIShell is capable of creating an indication subscription with the filter and
handler objects in one single step. This example is based upon `sblim-cmpi-base`
provider.

How to subscribe to an indication, please, follow the next example:

.. code-block:: python

    > c = connect("host", "privileged_user", "password")
    > c.subscribe_indication(
    ...    QueryLanguage="WQL",
    ...    Query='SELECT * FROM CIM_InstModification',
    ...    Name="cpu",
    ...    CreationNamespace="root/interop",
    ...    SubscriptionCreationClassName="CIM_IndicationSubscription",
    ...    FilterCreationClassName="CIM_IndicationFilter",
    ...    FilterSystemCreationClassName="CIM_ComputerSystem",
    ...    FilterSourceNamespace="root/cimv2",
    ...    HandlerCreationClassName="CIM_IndicationHandlerCIMXML",
    ...    HandlerSystemCreationClassName="CIM_ComputerSystem",
    ...    # destination computer, where the indications will be delivered
    ...    Destination="http://192.168.122.1:5988"
    ...  )
    LMIReturnValue(rval=True, rparams={}, errorstr="")
    >

The previous code can be simplified by omitting some optional parameters:

* *QueryLanguage*: *DMTF:CQL*
* *CreationNamespace*: *root/interop*
* *SubscriptionCreationClassName*: *CIM_IndicationSubscription*
* *FilterCreationClassName*: *CIM_IndicationFilter*
* *FilterSystemCreationClassName*: *CIM_ComputerSystem*
* *FilterSourceNamespace*: *root/cimv2*
* *HandlerCreationClassName*: *CIM_IndicationHandlerCIMXML*
* *HandlerSystemCreationClassName*: *CIM_ComputerSystem*

Simplified subscription:

.. code-block:: python

   > c = connect("host", "privileged_user", "password")
   > c.subscribe_indication(
   ...    Name="cpu",
   ...    Query='SELECT * FROM CIM_InstModification',
   ...    Destination="http://192.168.122.1:5988"
   ...  )
   LMIReturnValue(rval=True, rparams={}, errorstr="")
   >

**NOTE:** Make sure, that you are logged-in with an account, which has write
privileges in the *root/interop* namespace.

In this state, we have a indication subscription created.

Auto-delete subscriptions
^^^^^^^^^^^^^^^^^^^^^^^^^
By default all subscriptions created by LMIShell will be **auto-deleted**, when
the shell quits. To change this behavior, you can pass :samp:`Permanent=True`
keyword parameter to :py:meth:`.LMIConnection.subscribe_indication` call, which
will prevent LMIShell from deleting the subscription.

Listing subscribed indications
------------------------------
To list all the subscribed indications, run following code:

.. code-block:: python

    > c.print_subscribed_indications()
    ...
    > subscribed_ind_lst = c.subscribed_indications()
    >

Unsubscribing from an indications
---------------------------------
By default, the subscriptions created by the shell are auto-deleted, when the
shell quits.

If you want to delete the subscriptions sooner, you can use following methods:

.. code-block:: python

    > c.unsubscribe_indication(indication_name)
    LMIReturnValue(rval=True, rparams={}, errorstr="")
    > c.unsubscribe_all_indications()
    >

Indication handler
------------------
In the previous example, there is a local computer specified (the one, which
runs the shell), now we need to start a indication listener with our indication
handler function defined. This example continues (see previous one). It is also
possible to start another shell, script and start the indication listener
there.

See the following example:

.. code-block:: python

    > def handler(ind, arg1, arg2, **kwargs):
    ...    exported_objects = ind.exported_objects()
    ...    do_something_with(exported_objects)
    > listener = LmiIndicationListener("0.0.0.0", listening_port)
    > listener.add_handler("indication-name-XXXXXXXX", handler, arg1, arg2, **kwargs)
    > listener.start()
    >

The first argument of the handler is :py:class:`LMIIndication` object, which
contains list of methods and objects exported by the indication. Other
parameters are user specific; those arguments need to be specified, when adding
a handler to the listener. In the example, there is a special string used in
the :py:meth:`.LMIIndicationListener.add_handler` call; note the eight **"X"**
characters. Those characters will be replaced by random string, which is
generated by the listeners to avoid handler name clash. If you want to use that
random-based string, start indication listener first, then subscribe to an
indication, so the *Destination* property of a handler object contains
``<schema>://<hostname>/<random-based string>``.
