@Override
    public void joinedCluster()
    {
        // The local node joined a cluster.
        //
        // Upon joining a cluster, clustered caches are reset to their clustered equivalent (by the swap from the local
        // cache implementation to the clustered cache implementation that's done in the implementation of
        // org.jivesoftware.util.cache.CacheFactory.joinedCluster). This means that they now hold data that's
        // available on all other cluster nodes. Data that's available on the local node needs to be added again.
        restoreCacheContent();

        // We joined a cluster. Determine what components run on other nodes,
        // and raise events for those that are not running on this node.
        // Eventing should be limited to the local cluster node, as other nodes
        // would already have had events when the components became available to
        // them.
        componentCache.entrySet().stream()
            .filter( entrySet -> !entrySet.getValue().contains( XMPPServer.getInstance().getNodeID() ) )
            .forEach( entry -> {
                Log.debug( "The local cluster node joined the cluster. The component '{}' is living on one (or more) other cluster nodes, but not ours. Invoking the 'component registered' event, and requesting service info.", entry.getKey());
                notifyComponentRegistered( entry.getKey() );
                // Request one of the cluster nodes to sent us a NotifyComponentInfo instance. This async request does not block the current thread, and will update the instance eventually, after which notifications are sent out.
                CacheFactory.doClusterTask( new RequestComponentInfoNotification( entry.getKey(), XMPPServer.getInstance().getNodeID() ), entry.getValue().iterator().next().toByteArray() );
            } );

        // Additionally, let other cluster nodes know about the components that the local
        // node offers, to allow them to raise events if needed.
        componentCache.entrySet().stream()
            .filter( entrySet -> entrySet.getValue().contains( XMPPServer.getInstance().getNodeID() ) && entrySet.getValue().size() == 1 )
            .map( Map.Entry::getKey )
            .forEach( componentJID -> {
                Log.debug( "The local cluster node joined the cluster. The component '{}' is living on our cluster node, but not on any others. Invoking the 'component registered' (and if applicable, the 'component info received') event on the remote nodes.", componentJID );
                CacheFactory.doClusterTask( new NotifyComponentRegistered( componentJID ) );
                final IQ info = componentInfo.get( componentJID.toString() );
                if ( info != null )
                {
                    CacheFactory.doClusterTask( new NotifyComponentInfo( info ) );
                }
            } );
    }
Processes packets that were sent to this service. Currently only packets that were sent from
registered components are being processed. In the future, we may also process packet of
trusted clients. Trusted clients may be able to execute ad-hoc commands such as adding or
removing components.

@param packet the packet to process.
xmppserver/src/main/java/org/jivesoftware/openfire/component/InternalComponentManager.java