All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kie.uberfire.social.activities.persistence.SocialTimelineCacheClusterPersistence Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta5
Show newest version
/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package org.kie.uberfire.social.activities.persistence;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import org.kie.uberfire.social.activities.model.SocialActivitiesEvent;
import org.kie.uberfire.social.activities.model.SocialEventType;
import org.kie.uberfire.social.activities.model.SocialUser;
import org.kie.uberfire.social.activities.security.SocialSecurityConstraintsManager;
import org.kie.uberfire.social.activities.server.SocialUserServicesExtendedBackEndImpl;
import org.kie.uberfire.social.activities.service.SocialEventTypeRepositoryAPI;
import org.kie.uberfire.social.activities.service.SocialTimelinePersistenceAPI;
import org.kie.uberfire.social.activities.service.SocialUserPersistenceAPI;
import org.uberfire.commons.lifecycle.PriorityDisposableRegistry;
import org.uberfire.io.IOService;
import org.uberfire.java.nio.file.FileSystem;
import org.uberfire.java.nio.file.Path;

public class SocialTimelineCacheClusterPersistence extends SocialTimelineCachePersistence implements SocialTimelinePersistenceAPI {

    private SocialClusterMessaging socialClusterMessaging;

    public SocialTimelineCacheClusterPersistence( final Gson gson,
                                                  final Type gsonCollectionType,
                                                  final IOService ioService,
                                                  final SocialEventTypeRepositoryAPI socialEventTypeRepository,
                                                  final SocialUserPersistenceAPI socialUserPersistenceAPI,
                                                  final SocialClusterMessaging socialClusterMessaging,
                                                  final SocialUserServicesExtendedBackEndImpl userServicesBackend,
                                                  final FileSystem fileSystem,
                                                  final SocialSecurityConstraintsManager socialSecurityConstraintsManager ) {
        this.gson = gson;
        this.gsonCollectionType = gsonCollectionType;
        this.ioService = ioService;
        this.socialEventTypeRepository = socialEventTypeRepository;
        this.socialUserPersistenceAPI = socialUserPersistenceAPI;
        this.socialClusterMessaging = socialClusterMessaging;
        this.userServicesBackend = userServicesBackend;
        this.fileSystem = fileSystem;
        this.socialSecurityConstraintsManager = socialSecurityConstraintsManager;
        PriorityDisposableRegistry.register( this );
    }

    @Override
    public void persist( SocialActivitiesEvent event ) {
        SocialEventType type = socialEventTypeRepository.findType( event.getType() );
        persistEvent( event, type, true );
    }

    @Override
    public void persist( SocialUser user,
                         SocialActivitiesEvent event ) {
        if ( !clusterSyncEvent( event ) ) {
            registerNewEvent( user, event );
        } else {
            syncCluster( user );
        }

    }

    @Override
    public void saveAllEvents() {
        if ( !typeEventsTimelineCache.keySet().isEmpty() ) {
            try {
                final SocialEventType sampleType = typeEventsTimelineCache.keySet().iterator().next();
                Path timeLineDir = userServicesBackend.buildPath( SOCIAL_FILES, sampleType.name() );
                ioService.startBatch( timeLineDir.getFileSystem() );
                socialClusterMessaging.notifySomeInstanceisOnShutdown();
                saveAllTypeEvents();
                saveAllUserTimelines();
            } catch ( Exception e ) {
                System.out.println();
            } finally {
                ioService.endBatch();
            }
        }
    }

    private void registerNewEvent( SocialUser user,
                                   SocialActivitiesEvent event ) {
        List userEvents = userEventsTimelineFreshEvents.get( user.getUserName() );
        if ( userEvents == null ) {
            userEvents = new ArrayList();
        }
        userEvents.add( event );
        userEventsTimelineFreshEvents.put( user.getUserName(), userEvents );
        cacheControl( user );
    }

    private void syncCluster( SocialUser user ) {
        List myFreshEvents = userEventsTimelineFreshEvents.get( user.getUserName() );
        SocialCacheControl socialCacheControl = userEventsCacheControl.get( user.getUserName() );
        socialCacheControl.reset();
        List actualTypeTimeline = createOrGetUserTimeline( user.getUserName() );
        refreshCache( user.getUserName(), actualTypeTimeline );
        syncMyStaleItems( myFreshEvents, actualTypeTimeline, user );
    }

    private void syncCluster( SocialEventType eventType ) {
        List myFreshEvents = typeEventsFreshEvents.get( eventType );
        SocialCacheControl socialCacheControl = typeEventsCacheControl.get( eventType );
        socialCacheControl.reset();
        List actualTypeTimeline = createOrGetTypeTimeline( eventType );
        refreshCache( eventType, actualTypeTimeline );
        syncMyStaleItems( myFreshEvents, actualTypeTimeline, eventType );
    }

    void persist( SocialActivitiesEvent event,
                  SocialEventType type,
                  boolean sendClusterMsg ) {
        persistEvent( event, type, sendClusterMsg );
    }

    private void persistEvent( SocialActivitiesEvent event,
                               SocialEventType eventType,
                               boolean sendClusterMsg ) {
        if ( !clusterSyncEvent( event ) ) {
            registerNewEvent( event, eventType, sendClusterMsg );
        } else {
            syncCluster( eventType );
        }

    }

    private void registerNewEvent( SocialActivitiesEvent event,
                                   SocialEventType eventType,
                                   boolean sendClusterMsg ) {
        List typeEvents = typeEventsFreshEvents.get( eventType );
        typeEvents.add( event );
        typeEventsFreshEvents.put( eventType, typeEvents );
        cacheControl( event, eventType );

        if ( sendClusterMsg ) {
            socialClusterMessaging.notify( event );
        }
    }

    private boolean clusterSyncEvent( SocialActivitiesEvent event ) {
        return event.isDummyEvent();
    }

    private void syncMyStaleItems( List myFreshEvents,
                                   List storedTimeline,
                                   SocialEventType eventType ) {
        List unsavedEvents = findStaleEvents( myFreshEvents, storedTimeline );

        if ( !unsavedEvents.isEmpty() ) {
            List cacheEvents = typeEventsFreshEvents.get( eventType );
            cacheEvents.addAll( unsavedEvents );
            typeEventsFreshEvents.put( eventType, cacheEvents );
        }
    }

    private void syncMyStaleItems( List myFreshEvents,
                                   List storedTimeline,
                                   SocialUser user ) {
        List unsavedEvents = findStaleEvents( myFreshEvents, storedTimeline );
        if ( !unsavedEvents.isEmpty() ) {
            List cacheEvents = userEventsTimelineFreshEvents.get( user.getUserName() );
            cacheEvents.addAll( unsavedEvents );
            userEventsTimelineFreshEvents.put( user.getUserName(), cacheEvents );
        }

    }

    private List findStaleEvents( List myFreshEvents,
                                                         List storedTimeline
                                                       ) {
        List unsavedEvents = new ArrayList();
        for ( SocialActivitiesEvent myEvent : myFreshEvents ) {
            boolean hasEvent = false;
            for ( SocialActivitiesEvent storedEvents : storedTimeline ) {
                if ( storedEvents.equals( myEvent ) ) {
                    hasEvent = true;
                    break;
                }
            }
            if ( !hasEvent ) {
                unsavedEvents.add( myEvent );
            }
        }
        return unsavedEvents;
    }

    private void cacheControl( SocialUser user ) {
        SocialCacheControl socialCacheControl = userEventsCacheControl.get( user.getUserName() );
        if ( socialCacheControl == null ) {
            socialCacheControl = new SocialCacheControl();
            userEventsCacheControl.put( user.getUserName(), socialCacheControl );
        }
        socialCacheControl.registerNewEvent();
        if ( socialCacheControl.needToPersist() ) {
            Path userDir = getUserDirectory( user.getUserName() );
            try {
                ioService.startBatch( userDir.getFileSystem() );
                List storedEvents = storeTimeLineInFile( user );
                socialClusterMessaging.notifyTimeLineUpdate( user, storedEvents );
                socialCacheControl.reset();
            } finally {
                ioService.endBatch();
            }
        }
    }

    private void cacheControl( SocialActivitiesEvent event,
                               SocialEventType eventType ) {
        SocialEventType type = socialEventTypeRepository.findType( event.getType() );
        SocialCacheControl socialCacheControl = typeEventsCacheControl.get( type );
        socialCacheControl.registerNewEvent();
        if ( socialCacheControl.needToPersist() ) {
            Path timeLineDir = userServicesBackend.buildPath( SOCIAL_FILES, type.name() );
            try {
                ioService.startBatch( timeLineDir.getFileSystem() );
                socialClusterMessaging.notifyTimeLineUpdate( event );
                storeTimeLineInFile( eventType );
                socialCacheControl.reset();
            } finally {
                ioService.endBatch();
            }
        }
    }

    public void someNodeShutdownAndPersistEvents() {
        for ( SocialEventType socialEventType : typeEventsFreshEvents.keySet() ) {
            final List freshEvents = typeEventsFreshEvents.get( socialEventType );
            refreshCache( socialEventType, freshEvents );
        }
        for ( String user : userEventsTimelineFreshEvents.keySet() ) {
            final List userEvents = userEventsTimelineFreshEvents.get( user );
            refreshCache( user, userEvents );
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy