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

io.sarl.sre.janus.network.services.HazelcastContextService Maven / Gradle / Ivy

The newest version!
/**
 * $Id$
 * 
 * SARL is an general-purpose agent programming language.
 * More details on http://www.sarl.io
 * 
 * Copyright (C) 2014-2024 SARL.io, the Original Authors and Main Authors
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      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 io.sarl.sre.janus.network.services;

import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.hazelcast.map.MapEvent;
import io.bootique.di.Injector;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.annotation.Injectable;
import io.sarl.lang.core.annotation.SarlElementType;
import io.sarl.lang.core.annotation.SarlSpecification;
import io.sarl.lang.core.annotation.SyntheticMember;
import io.sarl.sre.janus.KernelScope;
import io.sarl.sre.janus.boot.configs.SreConfig;
import io.sarl.sre.janus.internal.Factories;
import io.sarl.sre.janus.services.context.Context;
import io.sarl.sre.janus.services.context.ContextFactory;
import io.sarl.sre.janus.services.context.MemoryBasedContextService;
import io.sarl.sre.janus.services.logging.LoggingService;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Provider;
import org.eclipse.xtend.lib.annotations.AccessorType;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.XbaseGenerated;

/**
 * Implementation of a context-space service that is connected to remote SRE with the Hazelcast framework.
 * 
 * @author Nicolas Gaud
 * @version janus.network 3.0.14.0 20241106-161408
 * @mavengroupid io.sarl.sre.janus
 * @mavenartifactid janus.network
 * @since 0.12
 */
@SarlSpecification("0.14")
@SarlElementType(10)
@Injectable
@XbaseGenerated
@SuppressWarnings("all")
public class HazelcastContextService extends MemoryBasedContextService {
  /**
   * Listener on Hazelcast's shared map events.
   * 
   * @author Nicolas Gaud
   * @version janus.network 3.0.14.0 20241106-161408
   * @mavengroupid io.sarl.sre.janus
   * @mavenartifactid janus.network
   * @since 0.12
   */
  @SarlSpecification("0.14")
  @SarlElementType(10)
  @XbaseGenerated
  protected static class DefaultSpacesMapListener implements EntryListener {
    private HazelcastContextService hazelcastContextService;

    public DefaultSpacesMapListener(final HazelcastContextService hazelcastContextService) {
      this.hazelcastContextService = hazelcastContextService;
    }

    public void entryAdded(final EntryEvent event) {
      this.hazelcastContextService.ensureDefaultSpaceDefinition(event.getKey(), event.getValue(), null);
    }

    public void entryUpdated(final EntryEvent event) {
    }

    public void entryRemoved(final EntryEvent event) {
      this.hazelcastContextService.removeDefaultSpaceDefinition(event.getKey(), event.getValue());
    }

    public void entryEvicted(final EntryEvent event) {
    }

    public void entryExpired(final EntryEvent event) {
    }

    public void mapCleared(final MapEvent event) {
    }

    public void mapEvicted(final MapEvent event) {
    }

    @Override
    @Pure
    @SyntheticMember
    public boolean equals(final Object obj) {
      return super.equals(obj);
    }

    @Override
    @Pure
    @SyntheticMember
    public int hashCode() {
      int result = super.hashCode();
      return result;
    }
  }

  /**
   * Local Hazelcast instance
   */
  @Accessors(AccessorType.PUBLIC_GETTER)
  private HazelcastInstance hazelcastInstance;

  /**
   * Map linking a context id to its associated default space id. This map must be
   * distributed and synchronized all over the network
   */
  private IMap defaultSpaces;

  /**
   * ID of the listener defined on defaultSpaces map
   */
  private UUID defaultSpacesListenerID;

  @Inject
  public HazelcastContextService(final SreConfig sreConfig, @KernelScope final Context rootContext, final LoggingService logger, final Injector injector, final ContextFactory factory, final Provider factories, final HazelcastInstance hazelcastInstance) {
    super(rootContext, logger, injector, factory, factories);
    this.hazelcastInstance = hazelcastInstance;
    final Supplier _function = () -> {
      return Messages.HazelcastContextService_0;
    };
    this.logger.info(_function);
    this.defaultSpaces = this.hazelcastInstance.getMap(sreConfig.getBoot().getRootContextID().toString());
    final Supplier _function_1 = () -> {
      return Messages.HazelcastContextService_1;
    };
    this.logger.info(_function_1);
    this.defaultSpaces.putIfAbsent(sreConfig.getBoot().getRootContextID(), sreConfig.getBoot().getRootSpaceID());
    final Supplier _function_2 = () -> {
      return Messages.HazelcastContextService_2;
    };
    this.logger.info(_function_2);
    EntryListener defaultSpacesListener = new HazelcastContextService.DefaultSpacesMapListener(this);
    this.defaultSpacesListenerID = this.defaultSpaces.addEntryListener(defaultSpacesListener, true);
    final Supplier _function_3 = () -> {
      return Messages.HazelcastContextService_3;
    };
    this.logger.info(_function_3);
  }

  @Override
  @Pure
  protected Logger createLogger(final LoggingService loggingService) {
    return loggingService.getKernelModuleLogger(Messages.HazelcastContextService_9);
  }

  protected Context newContextInstance(final UUID contextID, final UUID defaultSpaceID, final Agent owner) {
    final Supplier _function = () -> {
      return MessageFormat.format(Messages.HazelcastContextService_4, contextID, defaultSpaceID);
    };
    this.logger.info(_function);
    this.defaultSpaces.putIfAbsent(contextID, defaultSpaceID);
    return super.newContextInstance(contextID, defaultSpaceID, owner);
  }

  @Override
  public Context removeContext(final UUID contextID) {
    Context _xblockexpression = null;
    {
      this.defaultSpaces.remove(contextID);
      _xblockexpression = super.removeContext(contextID);
    }
    return _xblockexpression;
  }

  @Override
  public void onStart() {
    super.onStart();
  }

  protected Context ensureDefaultSpaceDefinition(final UUID contextID, final UUID defaultSpaceID, final Agent owner) {
    Context _xblockexpression = null;
    {
      final Supplier _function = () -> {
        return MessageFormat.format(Messages.HazelcastContextService_5, defaultSpaceID, contextID);
      };
      this.logger.info(_function);
      Context _xifexpression = null;
      boolean _containsKey = this.getContextInternalStructure().containsKey(contextID);
      if ((!_containsKey)) {
        _xifexpression = super.createContext(contextID, defaultSpaceID, owner);
      } else {
        UUID _iD = this.getContext(contextID).getDefaultSpace().getSpaceID().getID();
        boolean _notEquals = (!Objects.equals(_iD, defaultSpaceID));
        if (_notEquals) {
          final Supplier _function_1 = () -> {
            return MessageFormat.format(Messages.HazelcastContextService_6, defaultSpaceID, contextID);
          };
          this.logger.severe(_function_1);
        }
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }

  protected Context removeDefaultSpaceDefinition(final UUID contextID, final UUID defaultSpaceID) {
    Context _xifexpression = null;
    boolean _isPseudoEmpty = (this.getContext(contextID).getDefaultSpace().getNumberOfStrongParticipants() == 0);
    if (_isPseudoEmpty) {
      Context _xifexpression_1 = null;
      UUID _iD = this.getContext(contextID).getDefaultSpace().getSpaceID().getID();
      if ((_iD == defaultSpaceID)) {
        Context _xblockexpression = null;
        {
          final Supplier _function = () -> {
            return MessageFormat.format(Messages.HazelcastContextService_7, defaultSpaceID, contextID);
          };
          this.logger.info(_function);
          _xblockexpression = super.removeContext(contextID);
        }
        _xifexpression_1 = _xblockexpression;
      } else {
        final Supplier _function = () -> {
          return MessageFormat.format(Messages.HazelcastContextService_8, defaultSpaceID, contextID);
        };
        this.logger.severe(_function);
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }

  @Override
  public void onStop() {
    super.onStop();
    this.defaultSpaces.clear();
    this.defaultSpaces.removeEntryListener(this.defaultSpacesListenerID);
    boolean _isRunning = this.hazelcastInstance.getLifecycleService().isRunning();
    if (_isRunning) {
      this.hazelcastInstance.shutdown();
    }
  }

  @Override
  @Pure
  @SyntheticMember
  public boolean equals(final Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    HazelcastContextService other = (HazelcastContextService) obj;
    if (!Objects.equals(this.defaultSpacesListenerID, other.defaultSpacesListenerID))
      return false;
    return super.equals(obj);
  }

  @Override
  @Pure
  @SyntheticMember
  public int hashCode() {
    int result = super.hashCode();
    final int prime = 31;
    result = prime * result + Objects.hashCode(this.defaultSpacesListenerID);
    return result;
  }

  @Pure
  public HazelcastInstance getHazelcastInstance() {
    return this.hazelcastInstance;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy