Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.cisco.oss.foundation.directory.client;
  
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
 
 
 
 import static com.cisco.oss.foundation.directory.utils.ServiceInstanceUtils.copyModelInstFrom;
 import static com.cisco.oss.foundation.directory.utils.ServiceInstanceUtils.toServiceInstance;

InMemory client works as a in-memory server. so that sd-api can work as-like there is a real sd-server.

It's useful for unit/integration test in some case. The different with DirectoryServiceDummyClient is the dummy-client actually do nothing, but the in-memory client will maintain all service instances in memory.

Since:
1.2
See also:
DirectoryServiceDummyClient
 
 
     private static final Logger LOGGER = LoggerFactory.getLogger(DirectoryServiceInMemoryClient.class);
    
in-memory registry store K1 -> Service Name , K2 -> ProviderId
 
             ConcurrentHashMap<>();
 
     private static final int MAX_CHARGES_HISTORY_SIZE = 100;
 
             new ArrayBlockingQueue<>();
 
     private void addToHistory(InstanceChange<ModelServiceInstancechange) {
         if (change == null) {
             throw new IllegalArgumentException("ServiceInstanceChange should not be null");
         }
         //if history is full, remove the oldest one, because FIFO queue, so that take() will remove the oldest
         if (0 == .remainingCapacity()) {
             try {
                 .take();
             } catch (InterruptedException e) {
                 .error("error when try to remove change from history queue"e);
             }
         }
         try {
             .put(change);
         } catch (InterruptedException e) {
             .error("error when try to add change into history queue"e);
         }
         .debug("addToHistory {}. {} capacity left"change.remainingCapacity());
     }
 
     // ----------------------
     //  internal helper methods to convert between model-instance and provided-instance
     // ----------------------
     //for now, use the internal methods created here
     private static ModelService newModelService(String serviceName) {
         // in current sd-service implementation, the 'id' equals 'serviceName'
         // so we keep the pattern,the create/modify time for service are redundancies,
         // in instance level will use 0L 1970-Jun-01 as created time. (should not depends on it)
         return new ModelService(serviceNameserviceNamenew Date(0L));
 
     }
 
 
         ModelServiceInstance mInstance = new ModelServiceInstance();
 
         mInstance.setServiceName(instance.getServiceName());
         mInstance.setAddress(instance.getAddress());
         mInstance.setStatus(instance.getStatus());
         mInstance.setUri(instance.getUri());
 
         mInstance.setId(instance.getAddress());
         // use address as instanceId
         mInstance.setInstanceId(instance.getAddress());
        // use the monitor enabled by default
        mInstance.setMonitorEnabled(true);
        // Although problems in the model,
        // 1.) the xxxTime need not to be declared as Date, use long as milli-secs is enough
        // 2.) create-time should never be changed, good to be final
        // To maintain the compatible in JSON level. we need to keep using Date in 1.x until 2.0 when old protocol
        // compatibility is not a requirement. or we can re-define the model in 2.0
        final long now = System.currentTimeMillis();
        mInstance.setCreateTime(new Date(now));
        mInstance.setModifiedTime(new Date(now));
        //now use '1970-Jan-01' as initial value.
        mInstance.setHeartbeatTime(new Date(0L));
        // metadata
        mInstance.setMetadata(instance.getMetadata());
        return mInstance;
    }
        return new ProvidedServiceInstance(mInstance.getServiceName(), mInstance.getAddress(),
                mInstance.getUri(), mInstance.getStatus(),
                mInstance.getMetadata());
    }
    private static String objHashStr(Object o) {
        return o.getClass().getSimpleName() + "@" + Integer.toHexString(o.hashCode());
    }
    @Override
    public void registerInstance(ProvidedServiceInstance instance) {
        String serviceName = instance.getServiceName();
        if (previousMap == null) {
            .debug("new service Map is created for {}"serviceName);
        }
        ConcurrentMap<StringModelServiceInstanceiMap = .get(serviceName);
        ModelServiceInstance newInstance = newModelInstFromProvidedInst(instance);
        ModelServiceInstance previous = iMap.putIfAbsent(instance.getAddress(), newInstance);
        if (previous != null) {
            .debug("ModelServiceInstance id {} already registered by {} "instance.getAddress(), objHashStr(previous));
        } else {
            addToHistory(new InstanceChange<>(newInstance.getModifiedTime().getTime(),
                    newInstance.getServiceName(),
                    ..,
                    null,
                    copyModelInstFrom(newInstance)
            ));
            .debug("Registered new ModelServiceInstance {} with id {} "objHashStr(newInstance), instance.getAddress());
        }
    }
    @Deprecated
    @Override
    public void updateInstance(ProvidedServiceInstance instance) {
        String serviceName = instance.getServiceName();
        Map<StringModelServiceInstanceiMap = .get(serviceName);
        if (iMap == null) {
            .debug("Service {} not exist"serviceName);
        } else {
            ModelServiceInstance mInstance = iMap.get(instance.getAddress());
            if (mInstance == null) {
                .debug("ModelServiceInstance is not found by {}"instance.getAddress());
            } else {
                mInstance.setServiceName(instance.getServiceName());
                mInstance.setAddress(instance.getAddress());
                mInstance.setStatus(instance.getStatus());
                mInstance.setUri(instance.getUri());
                mInstance.setId(instance.getAddress());
                mInstance.setInstanceId(instance.getAddress());
                mInstance.setModifiedTime(new Date());
                mInstance.setMetadata(instance.getMetadata());
                .debug("ModelServiceInstance {} is update by {}"objHashStr(mInstance), objHashStr(instance));
            }
        }
    }
    private ModelServiceInstance getInstance(String serviceNameString instanceId) {
        Map<StringModelServiceInstanceiMap = .get(serviceName);
        if (iMap != null) {
            return iMap.get(instanceId);
        }
        return null;
    }
    @Override
    public void updateInstanceStatus(String serviceNameString instanceAddressOperationalStatus statusboolean isOwned) {
        if (status == null) {
            throw new NullPointerException("status is null");
        }
        ModelServiceInstance mInstance = getInstance(serviceNameinstanceAddress);
        if (mInstance != null) {
            if (!isOwned) {
                //IN this implementation, update don't care of if the service instance is owned by user
                .warn("do updateInstanceStatus even when isOwned is false");
            }
            final ModelServiceInstance old = copyModelInstFrom(mInstance);
            mInstance.setStatus(status);
            mInstance.setModifiedTime(new Date());
            addToHistory(new InstanceChange<>(mInstance.getModifiedTime().getTime(),
                    mInstance.getServiceName(),
                    ..,
                    old,
                    copyModelInstFrom(mInstance)
            ));
        } else {
            .warn("no service instance exist for {} {}"serviceNameinstanceAddress);
        }
    }
    @Override
    public void updateInstanceUri(String serviceNameString instanceAddressString uriboolean isOwned) {
        ModelServiceInstance mInstance = getInstance(serviceNameinstanceAddress);
        if (mInstance != null) {
            if (!isOwned) {
                //IN this implementation, we allow update don't care of if the service instance is owned by user
                .debug("do updateInstanceUri even when isOwned is false");
            }
            final ModelServiceInstance old = copyModelInstFrom(mInstance);
            mInstance.setUri(uri);
            mInstance.setModifiedTime(new Date());
            addToHistory(new InstanceChange<>(mInstance.getModifiedTime().getTime(),
                    mInstance.getServiceName(),
                    ..,
                    oldcopyModelInstFrom(mInstance)));
        } else {
            .debug("no service instance exist for {} {}"serviceNameinstanceAddress);
        }
    }
    @Override
    public void updateInstanceMetadata(String serviceNameString instanceAddressMap<StringStringmetadataboolean isOwned) {
        ModelServiceInstance mInstance = getInstance(serviceNameinstanceAddress);
        if (mInstance != null) {
            if (!isOwned) {
                //IN this implementation, we allow update don't care of if the service instance is owned by user
                .debug("do updateInstanceMetadata even when isOwned is false");
            }
            final ModelServiceInstance old = copyModelInstFrom(mInstance);
            mInstance.setMetadata(metadata);
            mInstance.setModifiedTime(new Date());
            addToHistory(new InstanceChange<>(mInstance.getModifiedTime().getTime(),
                    mInstance.getServiceName(),
                    ..,
                    oldcopyModelInstFrom(mInstance)));
        } else {
            .debug("no service instance exist for {} {}"serviceNameinstanceAddress);
        }
    }
    
    @Override
    public void unregisterInstance(String serviceNameString instanceAddressboolean isOwned) {
        ConcurrentMap<StringModelServiceInstanceiMap = .get(serviceName);
        if (iMap == null) {
            .warn("Service {} not exist"serviceName);
        } else {
            ModelServiceInstance previousInstance = iMap.remove(instanceAddress);
            if (previousInstance != null) {
                .debug("service instance {} removed by name : {} , address : {}"previousInstanceserviceNameinstanceAddress);
                addToHistory(new InstanceChange<>(previousInstance.getModifiedTime().getTime(),
                        previousInstance.getServiceName(),
                        ..,
                        copyModelInstFrom(previousInstance), null));
            } else {
                .debug("no service instance exist for {} {}"serviceNameinstanceAddress);
            }
        }
    }
    @Override
        HashMap<StringOperationResult<String>> result = new HashMap<>();
        for (Map.Entry<StringServiceInstanceHeartbeatentry : heartbeatMap.entrySet()) {
            String id = entry.getKey(); //What's Id means?
            ServiceInstanceHeartbeat heartbeat = entry.getValue();
            String serviceName = heartbeat.getServiceName();
            String providedAddress = heartbeat.getProviderAddress();
            ModelServiceInstance instance = getInstance(serviceNameprovidedAddress);
            if (instance != null) {
                final long now = System.currentTimeMillis();
                instance.setHeartbeatTime(new Date(now));
                instance.setModifiedTime(new Date(now));
                result.put(idnew OperationResult<String>(truenullnull));
                .debug("heart beat send ok for {}"instance);
            } else {
                .debug("no service instance exist for {} {}"serviceNameprovidedAddress);
                result.put(idnew OperationResult<String>(falsenullnew ServiceDirectoryError(.id)));
            }
        }
        return result;
    }
    @Override
    public ModelService lookupService(String serviceName) {
        Map<StringModelServiceInstanceiMap = .get(serviceName);
        if (iMap != null) {
            ModelService service = newModelService(serviceName);
            if (!iMap.isEmpty()) {
                List<ModelServiceInstanceinstanceList = new ArrayList<>(iMap.entrySet().size());
                List<LongmodifiedTimes = new ArrayList<>(instanceList.size());
                for (Map.Entry<StringModelServiceInstanceentry : iMap.entrySet()) {
                    ModelServiceInstance mInstance = copyModelInstFrom(entry.getValue());
                    instanceList.add(mInstance);
                    modifiedTimes.add(mInstance.getModifiedTime().getTime());
                }
                service.setServiceInstances(instanceList);
                // the latest modify time
                Collections.sort(modifiedTimes, Collections.reverseOrder());
                service.setModifiedTime(new Date(modifiedTimes.get(0)));
            }
            return service;
        } else {
            .debug("Service {} not exist"serviceName);
            return null;
        }
    }
    @Override
        List<ModelServiceInstanceinstanceList = new ArrayList<>();
        for (Map<StringModelServiceInstanceentry : .values()) {
            instanceList.addAll(entry.values());
        }
        .debug("getAllInstances() {}"instanceList);
        return Collections.unmodifiableList(instanceList);
    }
    @Override
    @Deprecated /* use lookUpChangedServiceInstancesSince() instead */
       throw new UnsupportedOperationException("not support the 1.1 method in DirectoryServiceInMemoryClient");
    }
    @Override
    public ModelMetadataKey getMetadataKey(String keyName) {
        throw new UnsupportedOperationException("get metadata is not supported now");
    }
    //-------------------------------
    // 1.2 API
    //-------------------------------
    public long getLastChangedTimeMills(String serviceName) {
        ModelService service = lookupService(serviceName);
        return service == null ? -1L : lookupService(serviceName).getModifiedTime().getTime();
    }
    public List<ServiceInstancelookUpChangedServiceInstancesSince(String serviceNamelong since) {
        List<ServiceInstancechanged = new ArrayList<>();
        // the latest in model
        ModelService latest = lookupService(serviceName);
        if (since < latest.getModifiedTime().getTime()) {
            // has changes , so where is the changes?
            for (ModelServiceInstance instance : latest.getServiceInstances()) {
                if (since < instance.getModifiedTime().getTime()) {
                    changed.add(toServiceInstance(instance));
                }
            }
        }
        return changed;
    }
    @Override
    public List<InstanceChange<ModelServiceInstance>> lookupChangesSince(String serviceNamelong since) {
        int index = -1;
        for (int i = 0; i < all.lengthi++) {
            if (all[i]. > since) {
                index = i;
                .debug("found changes {} at {} since {}"all[i].indexsince);
                break;
            }
        }
        if (index >= 0) {
            final int newLength = all.length - index;
            List<InstanceChange<ModelServiceInstance>> result = new ArrayList<>(newLength);
            for (int i = indexi < all.lengthi++) {
                if (all[i] == nullbreak//no more items. in the case
                //check if the instance is the service looked up for
                if (serviceName.equals(all[i].)) {
                    .debug("build change {} to result list"all[i]);
                    result.add(new InstanceChange<>(
                            all[i].,
                            all[i].,
                            all[i].,
                            all[i]. == null ? null :all[i].,
                            all[i]. == null ? null : all[i].));
                }
            }
            return result;
        }
        return Collections.emptyList();
    }
New to GrepCode? Check out our FAQ X