/** * Returns an updated version of the registration. * * @param registration the registration to update * @return the updated registration */ public Registration update(Registration registration) { Identity identity = this.identity != null ? this.identity : registration.getIdentity(); Link[] linkObject = this.objectLinks != null ? this.objectLinks : registration.getObjectLinks(); long lifeTimeInSec = this.lifeTimeInSec != null ? this.lifeTimeInSec : registration.getLifeTimeInSec(); BindingMode bindingMode = this.bindingMode != null ? this.bindingMode : registration.getBindingMode(); String smsNumber = this.smsNumber != null ? this.smsNumber : registration.getSmsNumber(); Map<String, String> additionalAttributes = this.additionalAttributes.isEmpty() ? registration.getAdditionalRegistrationAttributes() : updateAdditionalAttributes(registration.getAdditionalRegistrationAttributes()); // this needs to be done in any case, even if no properties have changed, in order // to extend the client registration time-to-live period ... Date lastUpdate = new Date(); Registration.Builder builder = new Registration.Builder(registration.getId(), registration.getEndpoint(), identity, registration.getRegistrationEndpointAddress()); builder.lwM2mVersion(registration.getLwM2mVersion()).lifeTimeInSec(lifeTimeInSec).smsNumber(smsNumber) .bindingMode(bindingMode).objectLinks(linkObject).registrationDate(registration.getRegistrationDate()) .lastUpdate(lastUpdate).additionalRegistrationAttributes(additionalAttributes); return builder.build(); }
@Override public JsonElement serialize(Registration src, Type typeOfSrc, JsonSerializationContext context) { JsonObject element = new JsonObject(); element.addProperty("endpoint", src.getEndpoint()); element.addProperty("registrationId", src.getId()); element.add("registrationDate", context.serialize(src.getRegistrationDate())); element.add("lastUpdate", context.serialize(src.getLastUpdate())); element.addProperty("address", src.getAddress().getHostAddress() + ":" + src.getPort()); element.addProperty("smsNumber", src.getSmsNumber()); element.addProperty("lwM2mVersion", src.getLwM2mVersion()); element.addProperty("lifetime", src.getLifeTimeInSec()); element.addProperty("bindingMode", src.getBindingMode().toString()); element.add("rootPath", context.serialize(src.getRootPath())); element.add("objectLinks", context.serialize(src.getSortedObjectLinks())); element.add("secure", context.serialize(src.getIdentity().isSecure())); element.add("additionalRegistrationAttributes", context.serialize(src.getAdditionalRegistrationAttributes())); if (src.usesQueueMode()) { element.add("sleeping", context.serialize(!presenceService.isClientAwake(src))); } return element; } }
private void removeAddrIndex(Jedis j, Registration registration) { byte[] regAddrKey = toRegAddrKey(registration.getSocketAddress()); byte[] epFromAddr = j.get(regAddrKey); if (Arrays.equals(epFromAddr, registration.getEndpoint().getBytes(UTF_8))) { j.del(regAddrKey); } }
private void addOrUpdateExpiration(Jedis j, Registration registration) { j.zadd(EXP_EP, registration.getExpirationTimeStamp(gracePeriod), registration.getEndpoint().getBytes(UTF_8)); }
@Override public void updated(RegistrationUpdate update, Registration updatedRegistration, Registration previousRegistration) { try (Jedis j = pool.getResource()) { // create registration entry byte[] k = (EP_UID + updatedRegistration.getEndpoint()).getBytes(); j.set(k, instanceUID.getBytes()); j.expire(k, updatedRegistration.getLifeTimeInSec().intValue()); } }
@Override public void onError(Exception e) { handlerError(destination.getEndpoint(), ticket, e); } });
@Override public Deregistration addRegistration(Registration registration) { try { lock.writeLock().lock(); Registration registrationRemoved = regsByEp.put(registration.getEndpoint(), registration); regsByRegId.put(registration.getId(), registration); // If a registration is already associated to this address we don't care as we only want to keep the most // recent binding. regsByAddr.put(registration.getSocketAddress(), registration); if (registrationRemoved != null) { Collection<Observation> observationsRemoved = unsafeRemoveAllObservations(registrationRemoved.getId()); if (!registrationRemoved.getSocketAddress().equals(registration.getSocketAddress())) { removeFromMap(regsByAddr, registrationRemoved.getSocketAddress(), registrationRemoved); } if (!registrationRemoved.getId().equals(registration.getId())) { removeFromMap(regsByRegId, registrationRemoved.getId(), registrationRemoved); } return new Deregistration(registrationRemoved, observationsRemoved); } } finally { lock.writeLock().unlock(); } return null; }
@Override public <T extends LwM2mResponse> void send(final Registration destination, final DownlinkRequest<T> request, long timeout, ResponseCallback<T> responseCallback, ErrorCallback errorCallback) { // Retrieve the objects definition final LwM2mModel model = modelProvider.getObjectModel(destination); // Create the CoAP request from LwM2m request CoapRequestBuilder coapRequestBuilder = new CoapRequestBuilder(destination.getIdentity(), destination.getRootPath(), destination.getId(), destination.getEndpoint(), model, encoder); request.accept(coapRequestBuilder); final Request coapRequest = coapRequestBuilder.getRequest(); // Add CoAP request callback MessageObserver obs = new AsyncRequestObserver<T>(coapRequest, responseCallback, errorCallback, timeout) { @Override public T buildResponse(Response coapResponse) { // Build LwM2m response LwM2mResponseBuilder<T> lwm2mResponseBuilder = new LwM2mResponseBuilder<>(coapRequest, coapResponse, destination, model, observationService, decoder); request.accept(lwm2mResponseBuilder); return lwm2mResponseBuilder.getResponse(); } }; coapRequest.addMessageObserver(obs); // Store pending request to cancel it on de-registration addPendingRequest(destination.getId(), coapRequest); // Send CoAP request asynchronously Endpoint endpoint = getEndpointForClient(destination); endpoint.sendRequest(coapRequest); }
if (!removeOnlyIfNotAlive || !r.isAlive(gracePeriod)) { long nbRemoved = j.del(toRegIdKey(r.getId())); if (nbRemoved > 0) { j.del(toEndpointKey(r.getEndpoint())); Collection<Observation> obsRemoved = unsafeRemoveAllObservations(j, r.getId()); removeAddrIndex(j, r); removeExpiration(j, r);
@Override public void run() { try { Collection<Registration> allRegs = new ArrayList<>(); try { lock.readLock().lock(); allRegs.addAll(regsByEp.values()); } finally { lock.readLock().unlock(); } for (Registration reg : allRegs) { if (!reg.isAlive()) { // force de-registration Deregistration removedRegistration = removeRegistration(reg.getId()); expirationListener.registrationExpired(removedRegistration.getRegistration(), removedRegistration.getObservations()); } } } catch (Exception e) { LOG.warn("Unexpected Exception while registration cleaning", e); } } }
@Override public int cancelObservations(Registration registration, String resourcepath) { if (registration == null || registration.getId() == null || resourcepath == null || resourcepath.isEmpty()) return 0; Set<Observation> observations = getObservations(registration.getId(), resourcepath); for (Observation observation : observations) { cancelObservation(observation); } return observations.size(); }
@Override public void sendCoapRequest(final Registration destination, final Request coapRequest, long timeout, CoapResponseCallback responseCallback, ErrorCallback errorCallback) { // Define destination EndpointContext context = EndpointContextUtil.extractContext(destination.getIdentity()); coapRequest.setDestinationContext(context); // Add CoAP request callback MessageObserver obs = new CoapAsyncRequestObserver(coapRequest, responseCallback, errorCallback, timeout); coapRequest.addMessageObserver(obs); // Store pending request to cancel it on de-registration addPendingRequest(destination.getId(), coapRequest); // Send CoAP request asynchronously Endpoint endpoint = getEndpointForClient(destination); endpoint.sendRequest(coapRequest); }
/** * Notify the listeners that the client state changed to {@link Presence#SLEEPING}. The state changes is produced * inside {@link PresenceStatus} when the timer expires or when the client doesn't respond to a request. * * @param reg the client's registration object */ public void setSleeping(Registration reg) { if (reg.usesQueueMode()) { PresenceStatus status = clientStatusList.get(reg.getEndpoint()); if (status != null) { boolean stateChanged = false; synchronized (status) { stateChanged = status.setSleeping(); stopClientAwakeTimer(reg); } if (stateChanged) { for (PresenceListener listener : listeners) { listener.onSleeping(reg); } } } } }
public void addListener(String endpoint, CoapMessageListener listener) { Registration registration = registry.getByEndpoint(endpoint); if (registration != null) { listeners.put(toStringAddress(registration.getIdentity().getPeerAddress()), listener); } }
/** * Gets the CoAP endpoint that should be used to communicate with a given client. * * @param registration the client * @return the CoAP endpoint bound to the same network address and port that the client connected to during * registration. If no such CoAP endpoint is available, the first CoAP endpoint from the list of registered * endpoints is returned */ private Endpoint getEndpointForClient(Registration registration) { for (Endpoint ep : endpoints) { InetSocketAddress endpointAddress = ep.getAddress(); if (endpointAddress.equals(registration.getRegistrationEndpointAddress())) { return ep; } } throw new IllegalStateException( "can't find the client endpoint for address : " + registration.getRegistrationEndpointAddress()); } }
@Override public void onResponse(LwM2mResponse response) { handleResponse(destination.getEndpoint(), ticket, response); } }, new ErrorCallback() {
@Override public Deregistration removeRegistration(String registrationId) { try { lock.writeLock().lock(); Registration registration = getRegistration(registrationId); if (registration != null) { Collection<Observation> observationsRemoved = unsafeRemoveAllObservations(registration.getId()); regsByEp.remove(registration.getEndpoint()); removeFromMap(regsByAddr, registration.getSocketAddress(), registration); removeFromMap(regsByRegId, registration.getId(), registration); return new Deregistration(registration, observationsRemoved); } return null; } finally { lock.writeLock().unlock(); } }
@Override public <T extends LwM2mResponse> T send(final Registration destination, final DownlinkRequest<T> request, long timeout) throws InterruptedException { // Retrieve the objects definition final LwM2mModel model = modelProvider.getObjectModel(destination); // Create the CoAP request from LwM2m request CoapRequestBuilder coapRequestBuilder = new CoapRequestBuilder(destination.getIdentity(), destination.getRootPath(), destination.getId(), destination.getEndpoint(), model, encoder); request.accept(coapRequestBuilder); final Request coapRequest = coapRequestBuilder.getRequest(); // Send CoAP request synchronously SyncRequestObserver<T> syncMessageObserver = new SyncRequestObserver<T>(coapRequest, timeout) { @Override public T buildResponse(Response coapResponse) { // Build LwM2m response LwM2mResponseBuilder<T> lwm2mResponseBuilder = new LwM2mResponseBuilder<>(coapRequest, coapResponse, destination, model, observationService, decoder); request.accept(lwm2mResponseBuilder); return lwm2mResponseBuilder.getResponse(); } }; coapRequest.addMessageObserver(syncMessageObserver); // Store pending request to cancel it on de-registration addPendingRequest(destination.getId(), coapRequest); // Send CoAP request asynchronously Endpoint endpoint = getEndpointForClient(destination); endpoint.sendRequest(coapRequest); // Wait for response, then return it return syncMessageObserver.waitForResponse(); }
if (!removeOnlyIfNotAlive || !r.isAlive(gracePeriod)) { long nbRemoved = j.del(toRegIdKey(r.getId())); if (nbRemoved > 0) { j.del(toEndpointKey(r.getEndpoint())); Collection<Observation> obsRemoved = unsafeRemoveAllObservations(j, r.getId()); removeAddrIndex(j, r); removeExpiration(j, r);
@Override public void registered(Registration registration, Registration previousReg, Collection<Observation> previousObsersations) { try (Jedis j = pool.getResource()) { // create registration entry byte[] k = (EP_UID + registration.getEndpoint()).getBytes(); j.set(k, instanceUID.getBytes()); j.expire(k, registration.getLifeTimeInSec().intValue()); } }