<commit_before>package brooklyn.web.console

import brooklyn.entity.Entity
import brooklyn.management.Task
import brooklyn.web.console.entity.SensorSummary
import brooklyn.event.Sensor
import brooklyn.entity.Effector
import brooklyn.web.console.entity.TaskSummary
import brooklyn.event.SensorEvent
import brooklyn.management.SubscriptionHandle
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.ConcurrentHashMap
import brooklyn.event.SensorEventListener
import java.util.concurrent.ConcurrentLinkedQueue
import brooklyn.event.AttributeSensor

class EntityService {

    static transactional = false
    def managementContextService

    private static final int CACHE_LIMIT = 10
    ConcurrentMap<String, ConcurrentMap<String, SensorSummary>> sensorCache = new ConcurrentHashMap<String, ConcurrentMap<String, SensorSummary>>()
    ConcurrentMap<String, SubscriptionHandle> subscriptions = new ConcurrentHashMap<String, SubscriptionHandle>()

    ConcurrentLinkedQueue<String> cacheQueue = new ConcurrentLinkedQueue<String>();

    public static class NoSuchEntity extends Exception {}

    public Collection<TaskSummary> getTasksOfEntity(String entityId) {
        return managementContextService.executionManager.getTasksWithTag(getEntity(entityId)).collect { new TaskSummary(it) }
    }

    private synchronized void unsubscribeEntitySensors(){
        String oldestEntity = cacheQueue.poll()
        if(managementContextService.subscriptionManager.unsubscribe(subscriptions.get(oldestEntity))){
            sensorCache.remove(oldestEntity)
            subscriptions.remove(oldestEntity)
        }
    }

    private void initializeEntitySensors(Entity entity) {
        synchronized (entity) {
            if(sensorCache.size() >= CACHE_LIMIT){
                unsubscribeEntitySensors()
            }

            sensorCache.putIfAbsent(entity.id, new ConcurrentHashMap<String, SensorSummary>())
            for (Sensor s : entity.entityClass.sensors) {
                if (s instanceof AttributeSensor) {
                    sensorCache[entity.id].putIfAbsent(s.name, new SensorSummary(s, entity.getAttribute(s)))
                }
            }

            if (!subscriptions.containsKey(entity.id)) {
                SubscriptionHandle handle = managementContextService.subscriptionManager.subscribe(entity, null,
                    new SensorEventListener() {
                        void onEvent(SensorEvent event) {
                            sensorCache.putIfAbsent(event.source.id, new ConcurrentHashMap<String, SensorSummary>())
                            sensorCache[event.source.id].put(event.sensor.name, new SensorSummary(event))
                        }
                    })
                cacheQueue.add(entity.id)
                subscriptions.put(entity.id, handle)
            }
        }
    }

    public Collection<SensorSummary> getSensorData(String entityId) {
        Entity entity = getEntity(entityId)
        if (!entity) throw new NoSuchEntity()

        if (!sensorCache.containsKey(entityId) || sensorCache[entityId].isEmpty()) {
            initializeEntitySensors(entity)
        }
        return sensorCache[entityId].values()
    }

    public Collection<Effector> getEffectorsOfEntity(String entityId) {
        Set<Effector> results = []
        Entity entity = getEntity(entityId)
        if (entity) {
            results.addAll(entity.entityClass.effectors)
        }

        return results
    }

    public Collection<Entity> getChildren(Entity parent) {
        Set<Entity> result = []

        if (parent.properties.containsKey("ownedChildren")) {
            parent.ownedChildren.each { result << it }
        }

        result
    }

    public List<Entity> getAncestorsOf(Entity child) {
        List<Entity> result = []
        Entity ancestor = child.getOwner()
        while (ancestor) {
            result.add(ancestor)
            ancestor = ancestor.getOwner()
        }
        return result
    }
    

    public boolean isChildOf(Entity child, Collection<Entity> parents) {
        parents.find { parent ->
            getChildren(parent).contains(child) || isChildOf(child, getChildren(parent))
        }
    }

    public Collection<Entity> getTopLevelEntities() {
        return managementContextService.applications<commit_msg>ENGR-1688: webapp now refreshes in demo<commit_after>package brooklyn.web.console

import brooklyn.entity.Entity
import brooklyn.web.console.entity.SensorSummary
import brooklyn.event.Sensor
import brooklyn.entity.Effector
import brooklyn.web.console.entity.TaskSummary
import brooklyn.event.SensorEvent
import brooklyn.management.SubscriptionHandle
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.ConcurrentHashMap
import brooklyn.event.SensorEventListener
import java.util.concurrent.ConcurrentLinkedQueue
import brooklyn.event.AttributeSensor

class EntityService {

    static transactional = false
    def managementContextService

    private static final int CACHE_LIMIT = 10
    ConcurrentMap<String, ConcurrentMap<String, SensorSummary>> sensorCache = new ConcurrentHashMap<String, ConcurrentMap<String, SensorSummary>>()
    ConcurrentMap<String, SubscriptionHandle> subscriptions = new ConcurrentHashMap<String, SubscriptionHandle>()

    ConcurrentLinkedQueue<String> cacheQueue = new ConcurrentLinkedQueue<String>();

    public static class NoSuchEntity extends Exception {}

    public Collection<TaskSummary> getTasksOfEntity(String entityId) {
        return managementContextService.executionManager.getTasksWithTag(getEntity(entityId)).collect { new TaskSummary(it) }
    }

    private synchronized void unsubscribeEntitySensors(){
        String oldestEntity = cacheQueue.poll()
        if(managementContextService.subscriptionManager.unsubscribe(subscriptions.get(oldestEntity))){
            sensorCache.remove(oldestEntity)
            subscriptions.remove(oldestEntity)
        }
    }

    private void initializeEntitySensors(Entity entity) {
        synchronized (entity) {
            if(sensorCache.size() >= CACHE_LIMIT){
                unsubscribeEntitySensors()
            }

            sensorCache.putIfAbsent(entity.id, new ConcurrentHashMap<String, SensorSummary>())
            for (Sensor s : entity.entityClass.sensors) {
                if (s instanceof AttributeSensor) {
                    sensorCache[entity.id].putIfAbsent(s.name, new SensorSummary(s, entity.getAttribute(s)))
                }
            }

            if (!subscriptions.containsKey(entity.id)) {
                SubscriptionHandle handle = managementContextService.subscriptionManager.subscribe(entity, null,
                    new SensorEventListener() {
                        void onEvent(SensorEvent event) {
                            sensorCache.putIfAbsent(event.source.id, new ConcurrentHashMap<String, SensorSummary>())
                            sensorCache[event.source.id].put(event.sensor.name, new SensorSummary(event))
                        }
                    })
                cacheQueue.add(entity.id)
                subscriptions.put(entity.id, handle)
            }
        }
    }

    public Collection<SensorSummary> getSensorData(String entityId) {
        Entity entity = getEntity(entityId)
        if (!entity) throw new NoSuchEntity()

        if (!sensorCache.containsKey(entityId) || sensorCache[entityId].isEmpty()) {
            initializeEntitySensors(entity)
        }
        return sensorCache[entityId].values()
    }

    public Collection<Effector> getEffectorsOfEntity(String entityId) {
        Set<Effector> results = []
        Entity entity = getEntity(entityId)
        if (entity) {
            results.addAll(entity.entityClass.effectors)
        }

        return results
    }

    public Collection<Entity> getChildren(Entity parent) {
        return parent.ownedChildren
    }

    public List<Entity> getAncestorsOf(Entity child) {
        List<Entity> result = []
        Entity ancestor = child.getOwner()
        while (ancestor) {
            result.add(ancestor)
            ancestor = ancestor.getOwner()
        }
        return result
    }
    

    public boolean isChildOf(Entity child, Collection<Entity> parents) {
        parents.find { parent ->
            getChildren(parent).contains(child) || isChildOf(child, getChildren(parent))
        }
    }

    public Collection<Entity> getTopLevelEntities() {
        return managementContextService.applications
{'fraction_non_alphanumeric': 0.08449046834549306, 'fraction_numerical': 0.0009413979759943516, 'mean_word_length': 2.795891022778026, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2499260', 'n_tokens_mistral': 2180, 'n_tokens_neox': 2151, 'n_words': 406}