| /* |
| * Copyright (c) 2020-2021 Kentyou. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Kentyou - initial API and implementation |
| */ |
| package org.eclipse.sensinact.gateway.core; |
| |
| import java.security.AccessController; |
| import java.security.InvalidKeyException; |
| import java.security.PrivilegedAction; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ServiceLoader; |
| import java.util.Set; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.CancellationException; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| import java.util.concurrent.Future; |
| import java.util.concurrent.atomic.AtomicInteger; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.sensinact.gateway.common.bundle.Mediator; |
| import org.eclipse.sensinact.gateway.common.constraint.Constraint; |
| import org.eclipse.sensinact.gateway.common.constraint.ConstraintFactory; |
| import org.eclipse.sensinact.gateway.common.constraint.InvalidConstraintDefinitionException; |
| import org.eclipse.sensinact.gateway.common.execution.Executable; |
| import org.eclipse.sensinact.gateway.core.Sessions.KeyExtractor; |
| import org.eclipse.sensinact.gateway.core.Sessions.KeyExtractorType; |
| import org.eclipse.sensinact.gateway.core.message.AbstractMidAgentCallback; |
| import org.eclipse.sensinact.gateway.core.message.LocalAgent; |
| import org.eclipse.sensinact.gateway.core.message.LocalAgentImpl; |
| import org.eclipse.sensinact.gateway.core.message.MidAgentCallback; |
| import org.eclipse.sensinact.gateway.core.message.MidCallbackException; |
| import org.eclipse.sensinact.gateway.core.message.Recipient; |
| import org.eclipse.sensinact.gateway.core.message.ResourceIntent; |
| import org.eclipse.sensinact.gateway.core.message.SnaAgent; |
| import org.eclipse.sensinact.gateway.core.message.SnaErrorfulMessage; |
| import org.eclipse.sensinact.gateway.core.message.SnaFilter; |
| import org.eclipse.sensinact.gateway.core.message.SnaMessage; |
| import org.eclipse.sensinact.gateway.core.message.SnaUpdateMessageImpl; |
| import org.eclipse.sensinact.gateway.core.method.AccessMethod; |
| import org.eclipse.sensinact.gateway.core.method.AccessMethodResponse; |
| import org.eclipse.sensinact.gateway.core.method.AccessMethodResponse.Status; |
| import org.eclipse.sensinact.gateway.core.method.RemoteAccessMethodExecutable; |
| import org.eclipse.sensinact.gateway.core.method.legacy.ActResponse; |
| import org.eclipse.sensinact.gateway.core.method.legacy.DescribeMethod; |
| import org.eclipse.sensinact.gateway.core.method.legacy.DescribeMethod.DescribeType; |
| import org.eclipse.sensinact.gateway.core.method.legacy.DescribeResponse; |
| import org.eclipse.sensinact.gateway.core.method.legacy.DescribeResponseBuilder; |
| import org.eclipse.sensinact.gateway.core.method.legacy.GetResponse; |
| import org.eclipse.sensinact.gateway.core.method.legacy.SetResponse; |
| import org.eclipse.sensinact.gateway.core.method.legacy.SubscribeResponse; |
| import org.eclipse.sensinact.gateway.core.method.legacy.UnsubscribeResponse; |
| import org.eclipse.sensinact.gateway.core.remote.RemoteCore; |
| import org.eclipse.sensinact.gateway.core.remote.SensinactCoreBaseIFaceManager; |
| import org.eclipse.sensinact.gateway.core.remote.SensinactCoreBaseIFaceManagerFactory; |
| import org.eclipse.sensinact.gateway.core.remote.SensinactCoreBaseIface; |
| import org.eclipse.sensinact.gateway.core.security.AccessNode; |
| import org.eclipse.sensinact.gateway.core.security.AccessTree; |
| import org.eclipse.sensinact.gateway.core.security.AccountConnector; |
| import org.eclipse.sensinact.gateway.core.security.Authentication; |
| import org.eclipse.sensinact.gateway.core.security.AuthenticationService; |
| import org.eclipse.sensinact.gateway.core.security.AuthenticationToken; |
| import org.eclipse.sensinact.gateway.core.security.Credentials; |
| import org.eclipse.sensinact.gateway.core.security.InvalidCredentialException; |
| import org.eclipse.sensinact.gateway.core.security.MutableAccessTree; |
| import org.eclipse.sensinact.gateway.core.security.SecuredAccess; |
| import org.eclipse.sensinact.gateway.core.security.SecuredAccessException; |
| import org.eclipse.sensinact.gateway.core.security.SecuredAccessFactory; |
| import org.eclipse.sensinact.gateway.core.security.SecurityDataStoreServiceFactory; |
| import org.eclipse.sensinact.gateway.core.security.User; |
| import org.eclipse.sensinact.gateway.core.security.UserKey; |
| import org.eclipse.sensinact.gateway.core.security.UserManager; |
| import org.eclipse.sensinact.gateway.core.security.UserManagerFactory; |
| import org.eclipse.sensinact.gateway.core.security.UserUpdater; |
| import org.eclipse.sensinact.gateway.datastore.api.DataStoreException; |
| import org.eclipse.sensinact.gateway.security.signature.api.BundleValidation; |
| import org.eclipse.sensinact.gateway.util.CryptoUtils; |
| import org.eclipse.sensinact.gateway.util.UriUtils; |
| import org.json.JSONArray; |
| import org.json.JSONObject; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleException; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.component.ComponentContext; |
| import org.osgi.service.component.annotations.Activate; |
| import org.osgi.service.component.annotations.Component; |
| import org.osgi.service.component.annotations.Deactivate; |
| import org.osgi.service.component.annotations.Reference; |
| import org.osgi.service.component.annotations.ReferenceCardinality; |
| import org.osgi.service.condpermadmin.ConditionalPermissionAdmin; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| |
| /** |
| * {@link Core} service implementation |
| * |
| * @author <a href="mailto:cmunilla@kentyou.com">Christophe Munilla</a> |
| */ |
| @Component(immediate=true) |
| public class SensiNact implements Core { |
| // ********************************************************************// |
| // NESTED DECLARATIONS // |
| // ********************************************************************// |
| |
| /** |
| * Abstract {@link Session} service implementation |
| */ |
| public abstract class SensiNactSession extends AbstractSession { |
| |
| /** |
| * Constructor |
| * |
| * @param identifier the String identifier of the Session to be instantiated |
| */ |
| public SensiNactSession(String identifier) { |
| super(identifier); |
| } |
| |
| @Override |
| public Set<ServiceProvider> serviceProviders(final String filter) { |
| return AccessController.doPrivileged(new PrivilegedAction<Set<ServiceProvider>>() { |
| @Override |
| public Set<ServiceProvider> run() { |
| return SensiNact.this.serviceProviders(SensiNactSession.this.getSessionId(), filter); |
| } |
| }); |
| } |
| |
| @Override |
| public ServiceProvider serviceProvider(final String serviceProviderName) { |
| ServiceProvider provider = AccessController.doPrivileged(new PrivilegedAction<ServiceProvider>() { |
| @Override |
| public ServiceProvider run() { |
| return SensiNact.this.serviceProvider(SensiNactSession.this.getSessionId(), serviceProviderName); |
| } |
| }); |
| return provider; |
| } |
| |
| @Override |
| public SubscribeResponse registerSessionAgent(String requestId, |
| final MidAgentCallback callback, final SnaFilter filter) { |
| |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| |
| boolean registered = AccessController.<Boolean>doPrivileged(new PrivilegedAction<Boolean>() { |
| @Override public Boolean run() {return sessionKey.registerAgent(callback, filter);}}); |
| |
| String uri = null; |
| if (filter != null) { |
| uri = filter.getSender(); |
| } else { |
| uri = UriUtils.PATH_SEPARATOR; |
| } |
| SubscribeResponse response = null; |
| if (registered) { |
| response = new SubscribeResponse(mediator, uri, Status.SUCCESS, 200); |
| response.setResponse(new JSONObject().put("subscriptionId", callback.getName())); |
| } else { |
| response = SensiNact.<JSONObject, SubscribeResponse>createErrorResponse( |
| mediator, AccessMethod.SUBSCRIBE, uri, 520, "Unable to subscribe", |
| null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public UnsubscribeResponse unregisterSessionAgent(String requestId, final String agentId) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| boolean unregistered = AccessController.<Boolean>doPrivileged(new PrivilegedAction<Boolean>() { |
| @Override |
| public Boolean run() { |
| if (sessionKey != null && sessionKey.getPublicKey() != null) { |
| return sessionKey.unregisterAgent(agentId); |
| } |
| return false; |
| } |
| }); |
| UnsubscribeResponse response = null; |
| if (unregistered) { |
| response = new UnsubscribeResponse(mediator, UriUtils.PATH_SEPARATOR, Status.SUCCESS, 200); |
| response.setResponse(new JSONObject().put("message", "The agent has been properly unregistered")); |
| |
| } else { |
| response = SensiNact.<JSONObject, UnsubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.UNSUBSCRIBE, UriUtils.PATH_SEPARATOR, 520, "Unable to unsubscribe", null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public SubscribeResponse registerSessionIntent(String requestId, Executable<Boolean, Void> callback, |
| String... resourcePath) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| final ResourceIntent intent = new ResourceIntent(mediator, sessionKey.getPublicKey(), callback, resourcePath) { |
| @Override |
| public boolean isAccessible(String path) { |
| return SensiNactSession.this.isAccessible(path); |
| } |
| @Override |
| public String namespace() { |
| return SensiNact.this.namespace(); |
| } |
| }; |
| boolean registered = AccessController.<Boolean>doPrivileged(new PrivilegedAction<Boolean>() { |
| @Override |
| public Boolean run() { |
| return sessionKey.registerAgent(intent.getName(), intent); |
| } |
| }); |
| SubscribeResponse response = null; |
| if (registered) { |
| response = new SubscribeResponse(mediator, intent.getCommonPath(), Status.SUCCESS, 200); |
| response.setResponse(new JSONObject().put("subscriptionId", intent.getName())); |
| } else { |
| response = SensiNact.<JSONObject, SubscribeResponse>createErrorResponse( |
| mediator, AccessMethod.SUBSCRIBE, intent.getCommonPath(), 520, "Unable to subscribe", |
| null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public UnsubscribeResponse unregisterSessionIntent(String requestId, final String intentId) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| boolean unregistered = AccessController.<Boolean>doPrivileged(new PrivilegedAction<Boolean>() { |
| @Override |
| public Boolean run() { |
| if (sessionKey != null && sessionKey.getPublicKey() != null) { |
| return sessionKey.unregisterAgent(intentId); |
| } |
| return false; |
| } |
| }); |
| UnsubscribeResponse response = null; |
| if (unregistered) { |
| response = new UnsubscribeResponse(mediator, UriUtils.PATH_SEPARATOR, Status.SUCCESS, 200); |
| response.setResponse(new JSONObject().put("message", "The intent has been properly unregistered")); |
| |
| } else { |
| response = SensiNact.<JSONObject, UnsubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.UNSUBSCRIBE, UriUtils.PATH_SEPARATOR, 520, "Unable to unsubscribe", null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public GetResponse get(String requestId, final String serviceProviderId, final String serviceId, |
| final String resourceId, final String attributeId) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId, resourceId); |
| |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| GetResponse response = null; |
| |
| if (resource != null) { |
| if (attributeId == null) { |
| if (!resource.getType().equals(Resource.Type.ACTION)) |
| response = ((DataResource) resource).get(); |
| else |
| response = SensiNact.<JSONObject, GetResponse>createErrorResponse(mediator, AccessMethod.GET, uri, 404, "Unknown Method", null); |
| } else |
| response = resource.get(attributeId); |
| return tatooRequestId(requestId, response); |
| } |
| if (serviceProviderId.indexOf('(') < 0 && sessionKey.localID() != 0) { |
| |
| response = SensiNact.<JSONObject, GetResponse>createErrorResponse(mediator, AccessMethod.GET, uri, |
| SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.get(sessionKey.getToken(), serviceProviderId, serviceId, |
| resourceId, attributeId); |
| } |
| }); |
| try { |
| response = this.<GetResponse>responseFromJSONObject(mediator, uri, AccessMethod.GET, object); |
| } catch (Exception e) { |
| response = SensiNact.<JSONObject, GetResponse>createErrorResponse(mediator, AccessMethod.GET, uri, |
| SnaErrorfulMessage.INTERNAL_SERVER_ERROR_CODE, "Internal server error", e); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public SetResponse set(String requestId, final String serviceProviderId, final String serviceId, |
| final String resourceId, final String attributeId, final Object parameter) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId, |
| resourceId); |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| SetResponse response = null; |
| |
| if (resource != null) { |
| if (attributeId == null) { |
| if (!resource.getType().equals(Resource.Type.ACTION)) { |
| response = ((DataResource) resource).set(parameter); |
| |
| } else { |
| response = SensiNact.<JSONObject, SetResponse>createErrorResponse(mediator, AccessMethod.SET, |
| uri, 404, "Unknown Method", null); |
| } |
| } else { |
| response = resource.set(attributeId, parameter); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<JSONObject, SetResponse>createErrorResponse(mediator, AccessMethod.SET, uri, |
| SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found", null); |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.set(sessionKey.getPublicKey(), serviceProviderId, serviceId, |
| resourceId, attributeId, parameter); |
| } |
| }); |
| try { |
| response = this.<SetResponse>responseFromJSONObject(mediator, uri, AccessMethod.SET, object); |
| } catch (Exception e) { |
| response = SensiNact.<JSONObject, SetResponse>createErrorResponse(mediator, AccessMethod.SET, uri, |
| SnaErrorfulMessage.INTERNAL_SERVER_ERROR_CODE, "Internal server error", e); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public ActResponse act(String requestId, final String serviceProviderId, final String serviceId, |
| final String resourceId, final Object[] parameters) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| ActResponse response = null; |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId, |
| resourceId); |
| |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| |
| if (resource != null) { |
| if (!resource.getType().equals(Resource.Type.ACTION)) { |
| response = SensiNact.<JSONObject, ActResponse>createErrorResponse(mediator, AccessMethod.ACT, uri, |
| 404, "Unknown Method", null); |
| } else { |
| if (parameters != null && parameters.length > 0) { |
| response = ((ActionResource) resource).act(parameters); |
| |
| } else { |
| response = ((ActionResource) resource).act(); |
| } |
| } |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<JSONObject, ActResponse>createErrorResponse(mediator, AccessMethod.ACT, uri, |
| SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found", null); |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.act(sessionKey.getPublicKey(), serviceProviderId, serviceId, |
| resourceId, parameters); |
| } |
| }); |
| try { |
| response = this.<ActResponse>responseFromJSONObject(mediator, uri, AccessMethod.ACT, object); |
| } catch (Exception e) { |
| response = SensiNact.<JSONObject, ActResponse>createErrorResponse(mediator, AccessMethod.ACT, uri, |
| SnaErrorfulMessage.INTERNAL_SERVER_ERROR_CODE, "Internal server error", e); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public SubscribeResponse subscribe(final String requestId, final String serviceProviderId, final String serviceId, |
| final String resourceId, final Recipient recipient, final JSONArray conditions, final String policy) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, getSessionId())); |
| } |
| SubscribeResponse response = null; |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, |
| serviceId, resourceId); |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| |
| if (resource != null) { |
| if (!resource.getType().equals(Resource.Type.ACTION)) { |
| Constraint constraint = null; |
| if (conditions != null && conditions.length() > 0) { |
| try { |
| constraint = ConstraintFactory.Loader.load(mediator.getClassLoader(), conditions); |
| |
| } catch (InvalidConstraintDefinitionException e) { |
| mediator.error(e); |
| } |
| } |
| response = ((DataResource) resource).subscribe(recipient, (constraint == null |
| ? Collections.<Constraint>emptySet():Collections.<Constraint>singleton(constraint)),policy); |
| } else { |
| response = SensiNact.<JSONObject, SubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.SUBSCRIBE, uri, 404, "Unknown Method", null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| Boolean acc = SensiNact.this.remoteCoreInvocation(uri, new Executable<SensinactCoreBaseIface,Boolean>(){ |
| @Override |
| public Boolean execute(SensinactCoreBaseIface core) throws Exception { |
| return core.isAccessible(sessionKey.getPublicKey(), serviceProviderId, serviceId, resourceId); |
| } |
| }); |
| boolean accessible = acc==null?false:acc.booleanValue(); |
| |
| if (sessionKey.localID() != 0 || !accessible) { |
| response = SensiNact.<JSONObject, SubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.SUBSCRIBE, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found", null); |
| return tatooRequestId(requestId, response); |
| } |
| final String uriRemote=String.format("/%s/%s/%s",serviceProviderId,serviceId,resourceId); |
| response=new SubscribeResponse(mediator,uriRemote,Status.SUCCESS); |
| response.setResponse(new JSONObject().put("subscriptionId",recipient.toString())); |
| MidAgentCallback cb = new AbstractMidAgentCallback(true,true,recipient.toString()){ |
| @Override |
| public void doHandle(SnaUpdateMessageImpl message) throws MidCallbackException { |
| JSONObject oj=new JSONObject(message.getJSON()); |
| if(oj.getString("uri").startsWith(uriRemote)) { |
| LOG.info("remote: Subscription response {}",oj.toString()); |
| try { |
| recipient.callback(requestId, new SnaMessage[]{message}); |
| } catch (Exception e) { |
| throw new MidCallbackException(e); |
| } |
| } |
| } |
| }; |
| SnaFilter filter = new SnaFilter(mediator, uriRemote.concat("/value"), true, false); |
| filter.addHandledType(SnaMessage.Type.UPDATE); |
| Constraint constraint = null; |
| if (conditions != null && conditions.length() > 0) { |
| try { |
| constraint = ConstraintFactory.Loader.load(mediator.getClassLoader(), conditions); |
| } catch (InvalidConstraintDefinitionException e) { |
| mediator.error(e); |
| } |
| } |
| filter.addCondition(constraint); |
| SensiNact.this.registerAgent(mediator, cb, filter); |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public UnsubscribeResponse unsubscribe(String requestId, final String serviceProviderId, final String serviceId, |
| final String resourceId, final String subscriptionId) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, |
| getSessionId())); |
| } |
| UnsubscribeResponse response = null; |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId, |
| resourceId); |
| |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| |
| if (resource != null) { |
| if (!resource.getType().equals(Resource.Type.ACTION)) { |
| response = ((DataResource) resource).unsubscribe(subscriptionId); |
| |
| } else { |
| response = SensiNact.<JSONObject, UnsubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.UNSUBSCRIBE, uri, 404, "Unknown Method", null); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| Boolean acc = SensiNact.this.remoteCoreInvocation(uri, new Executable<SensinactCoreBaseIface,Boolean>(){ |
| @Override |
| public Boolean execute(SensinactCoreBaseIface core) throws Exception { |
| return core.isAccessible(sessionKey.getPublicKey(), serviceProviderId, serviceId, resourceId); |
| } |
| }); |
| boolean accessible = acc==null?false:acc.booleanValue(); |
| |
| if (sessionKey.localID() != 0 || !accessible) { |
| response = SensiNact.<JSONObject, UnsubscribeResponse>createErrorResponse(mediator, |
| AccessMethod.UNSUBSCRIBE, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found",null); |
| return tatooRequestId(requestId, response); |
| } |
| final String uriRemote=String.format("/%s/%s/%s",serviceProviderId,serviceId,resourceId); |
| response=new UnsubscribeResponse(mediator,uriRemote,Status.SUCCESS, 200); |
| response.setResponse(new JSONObject().put("message","unsubscription done")); |
| mediator.callService(SnaAgent.class, new StringBuilder().append("(org.eclipse.sensinact.gateway.agent.id=" |
| ).append(subscriptionId).append(")").toString(), new Executable<SnaAgent,Void>(){ |
| @Override |
| public Void execute(SnaAgent agent) throws Exception { |
| agent.stop(); |
| return null; |
| } |
| } |
| ); |
| return tatooRequestId(requestId, response); |
| |
| } |
| |
| @Override |
| public DescribeResponse<String> getAll(String requestId, String filter, FilteringCollection filterCollection) { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, |
| getSessionId())); |
| } |
| DescribeResponse<String> response = null; |
| DescribeMethod<String> method = new DescribeMethod<String>(mediator, UriUtils.PATH_SEPARATOR, null, |
| DescribeType.COMPLETE_LIST); |
| |
| DescribeResponseBuilder<String> builder = method.createAccessMethodResponseBuilder(null); |
| |
| final String ldapFilter; |
| if (filterCollection != null) { |
| ldapFilter = filterCollection.composeLDAPFormatedFilter(filter); |
| |
| } else { |
| ldapFilter = filter; |
| } |
| String all = AccessController.doPrivileged(new PrivilegedAction<String>() { |
| @Override |
| public String run() { |
| return SensiNact.this.getAll(SensiNactSession.this.getSessionId(), ldapFilter); |
| } |
| }); |
| if (all == null) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.COMPLETE_LIST, UriUtils.PATH_SEPARATOR, |
| SnaErrorfulMessage.INTERNAL_SERVER_ERROR_CODE, "Internal server error", null); |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| builder.setAccessMethodObjectResult(all); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| return tatooRequestId(requestId, response); |
| } |
| String result = new StringBuilder().append("[").append(all).append("]").toString(); |
| |
| if (filterCollection != null) { |
| result = filterCollection.apply(result); |
| } |
| builder.setAccessMethodObjectResult(result); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| |
| if (filterCollection != null) { |
| response.put("filters", new JSONArray(filterCollection.filterJsonDefinition()), |
| filterCollection.hideFilter()); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public DescribeResponse<String> getProviders(String requestId, FilteringCollection filterCollection) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| DescribeResponse<String> response = null; |
| DescribeMethod<String> method = new DescribeMethod<String>(mediator, UriUtils.PATH_SEPARATOR, null, |
| DescribeType.PROVIDERS_LIST); |
| |
| DescribeResponseBuilder<String> builder = method.createAccessMethodResponseBuilder(null); |
| final String ldapFilter; |
| if (filterCollection != null) { |
| ldapFilter = filterCollection.composeLDAPFormatedFilter(null); |
| } else { |
| ldapFilter = null; |
| } |
| String providers = AccessController.doPrivileged(new PrivilegedAction<String>() { |
| @Override |
| public String run() { |
| return SensiNact.this.getProviders(SensiNactSession.this.getSessionId(), ldapFilter); |
| } |
| }); |
| if (providers == null) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.PROVIDERS_LIST, UriUtils.PATH_SEPARATOR, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, |
| "Internal server error", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| builder.setAccessMethodObjectResult(providers); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| return tatooRequestId(requestId, response); |
| } |
| String result = new StringBuilder().append("[").append(providers).append("]").toString(); |
| |
| if (filterCollection != null) { |
| result = filterCollection.apply(result); |
| } |
| builder.setAccessMethodObjectResult(result); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| if (filterCollection != null) { |
| response.put("filters", new JSONArray(filterCollection.filterJsonDefinition()), |
| filterCollection.hideFilter()); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public DescribeResponse<JSONObject> getProvider(String requestId, final String serviceProviderId) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId); |
| |
| DescribeResponse<JSONObject> response = null; |
| |
| DescribeMethod<JSONObject> method = new DescribeMethod<JSONObject>(mediator, uri, null, |
| DescribeType.PROVIDER); |
| |
| DescribeResponseBuilder<JSONObject> builder = method.createAccessMethodResponseBuilder(null); |
| |
| ServiceProvider provider = this.serviceProvider(serviceProviderId); |
| |
| if (provider != null) { |
| builder.setAccessMethodObjectResult(new JSONObject(provider.getDescription().getJSON())); |
| |
| return tatooRequestId(requestId, builder.createAccessMethodResponse()); |
| } |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<JSONObject, DescribeResponse<JSONObject>>createErrorResponse(mediator, |
| DescribeType.PROVIDER, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, |
| "Service provider not found", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.getProvider(SensiNactSession.this.getSessionId(), serviceProviderId); |
| } |
| }); |
| response = describeFromJSONObject(mediator, builder, DescribeType.PROVIDER, object); |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public DescribeResponse<String> getServices(String requestId, final String serviceProviderId, |
| FilteringCollection filterCollection) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId); |
| DescribeResponse<String> response = null; |
| DescribeMethod<String> method = new DescribeMethod<String>(mediator, uri, null, DescribeType.SERVICES_LIST); |
| DescribeResponseBuilder<String> builder = method.createAccessMethodResponseBuilder(null); |
| ServiceProvider provider = this.serviceProvider(serviceProviderId); |
| String services = null; |
| |
| if (provider == null) { |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.SERVICES_LIST, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, |
| "Service provider not found", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| services = AccessController.doPrivileged(new PrivilegedAction<String>() { |
| @Override |
| public String run() { |
| return SensiNact.this.getServices(SensiNactSession.this.getSessionId(), serviceProviderId); |
| } |
| }); |
| } else { |
| services = this.joinElementNames(provider); |
| } |
| if (services == null) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.SERVICES_LIST, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, |
| "Service provider not found", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| builder.setAccessMethodObjectResult(services); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| return tatooRequestId(requestId, response); |
| } |
| String result = new StringBuilder().append("[").append(services).append("]").toString(); |
| |
| if (filterCollection != null) { |
| result = filterCollection.apply(result); |
| } |
| builder.setAccessMethodObjectResult(result); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| |
| if (filterCollection != null) { |
| response.put("filters", new JSONArray(filterCollection.filterJsonDefinition()), |
| filterCollection.hideFilter()); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public DescribeResponse<JSONObject> getService(String requestId, final String serviceProviderId, |
| final String serviceId) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId); |
| |
| DescribeResponse<JSONObject> response = null; |
| |
| DescribeMethod<JSONObject> method = new DescribeMethod<JSONObject>(mediator, uri, null, |
| DescribeType.SERVICE); |
| |
| DescribeResponseBuilder<JSONObject> builder = method.createAccessMethodResponseBuilder(null); |
| |
| Service service = this.service(serviceProviderId, serviceId); |
| |
| if (service != null) { |
| builder.setAccessMethodObjectResult(new JSONObject(service.getDescription().getJSON())); |
| |
| return tatooRequestId(requestId, builder.createAccessMethodResponse()); |
| } |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<JSONObject, DescribeResponse<JSONObject>>createErrorResponse(mediator, |
| DescribeType.SERVICE, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Service not found", null); |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.getService(SensiNactSession.this.getSessionId(), serviceProviderId, |
| serviceId); |
| } |
| }); |
| return tatooRequestId(requestId, describeFromJSONObject(mediator, builder, DescribeType.SERVICE, object)); |
| } |
| |
| @Override |
| public DescribeResponse<String> getResources(String requestId, final String serviceProviderId, |
| final String serviceId, FilteringCollection filterCollection) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId); |
| |
| DescribeResponse<String> response = null; |
| |
| DescribeMethod<String> method = new DescribeMethod<String>(mediator, uri, null, |
| DescribeType.RESOURCES_LIST); |
| |
| DescribeResponseBuilder<String> builder = method.createAccessMethodResponseBuilder(null); |
| |
| Service service = this.service(serviceProviderId, serviceId); |
| String resources = null; |
| |
| if (service == null) { |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.RESOURCES_LIST, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, |
| "Service not found", null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| resources = AccessController.doPrivileged(new PrivilegedAction<String>() { |
| @Override |
| public String run() { |
| return SensiNact.this.getResources(SensiNactSession.this.getSessionId(), serviceProviderId, |
| serviceId); |
| } |
| }); |
| } else { |
| resources = this.joinElementNames(service); |
| } |
| if (resources == null) { |
| response = SensiNact.<String, DescribeResponse<String>>createErrorResponse(mediator, |
| DescribeType.RESOURCES_LIST, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Service not found", |
| null); |
| |
| return tatooRequestId(requestId, response); |
| } |
| if (sessionKey.localID() != 0) { |
| builder.setAccessMethodObjectResult(resources); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| return tatooRequestId(requestId, response); |
| } |
| String result = new StringBuilder().append("[").append(resources).append("]").toString(); |
| |
| if (filterCollection != null) { |
| result = filterCollection.apply(result); |
| } |
| builder.setAccessMethodObjectResult(result); |
| response = builder.createAccessMethodResponse(Status.SUCCESS); |
| |
| if (filterCollection != null) { |
| response.put("filters", new JSONArray(filterCollection.filterJsonDefinition()), |
| filterCollection.hideFilter()); |
| } |
| return tatooRequestId(requestId, response); |
| } |
| |
| @Override |
| public DescribeResponse<JSONObject> getResource(final String requestId, final String serviceProviderId, |
| final String serviceId, final String resourceId) { |
| SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| |
| String uri = getUri((sessionKey.localID() != 0), SensiNact.this.namespace(), serviceProviderId, serviceId, |
| resourceId); |
| |
| DescribeResponseBuilder<JSONObject> builder = new DescribeMethod<JSONObject>(mediator, uri, null, |
| DescribeType.RESOURCE).createAccessMethodResponseBuilder(null); |
| |
| Resource resource = this.resource(serviceProviderId, serviceId, resourceId); |
| |
| DescribeResponse<JSONObject> response = null; |
| |
| if (resource != null) { |
| builder.setAccessMethodObjectResult(new JSONObject(resource.getDescription().getJSONDescription())); |
| return tatooRequestId(requestId, builder.createAccessMethodResponse()); |
| } |
| if (sessionKey.localID() != 0) { |
| response = SensiNact.<JSONObject, DescribeResponse<JSONObject>>createErrorResponse(mediator, |
| DescribeType.RESOURCE, uri, SnaErrorfulMessage.NOT_FOUND_ERROR_CODE, "Resource not found", null); |
| return tatooRequestId(requestId, response); |
| } |
| JSONObject object = AccessController.doPrivileged(new PrivilegedAction<JSONObject>() { |
| @Override |
| public JSONObject run() { |
| return SensiNact.this.getResource(SensiNactSession.this.getSessionId(), serviceProviderId, |
| serviceId, resourceId); |
| } |
| }); |
| return tatooRequestId(requestId, describeFromJSONObject(mediator, builder, DescribeType.RESOURCE, object)); |
| } |
| |
| @Override |
| public boolean isAccessible(String serviceProviderId, String serviceId, String resourceId) { |
| return isAccessible(UriUtils.getUri(new String[] {serviceProviderId, serviceId, resourceId})); |
| } |
| |
| /** |
| * Returns true if the model element targeted by the String path argument |
| * exists and is accessible to this {@link Session}. Returns false if the |
| * model element does not exist or is not accessible to this {@link Session} |
| * |
| * @param path the String path of the targeted model element |
| * |
| * @return |
| * <ul> |
| * <li>true if the targeted model element exists and is accessible to this |
| * {@link Session}</li> |
| * <li>false otherwise</li> |
| * </ul> |
| */ |
| private final boolean isAccessible(final String path) { |
| final SessionKey sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>( |
| KeyExtractorType.TOKEN, this.getSessionId())); |
| Boolean accessible = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
| @Override |
| public Boolean run() { |
| boolean isAccessible = SensiNact.this.isAccessible(sessionKey, path); |
| if(!isAccessible && sessionKey.localID() == 0){ |
| String[] uriElements = UriUtils.getUriElements(path); |
| if(uriElements.length < 3) |
| return false; |
| final String[] providerElements = uriElements[0].split(":"); |
| Boolean bool = remoteCoreInvocation(uriElements[0], new Executable<SensinactCoreBaseIface, Boolean>() { |
| @Override |
| public Boolean execute(SensinactCoreBaseIface core) throws Exception { |
| if(core.isAccessible(sessionKey.getPublicKey(), providerElements.length>1?providerElements[1]:providerElements[0], |
| uriElements[1], uriElements[2])) |
| return true; |
| return false; |
| } |
| }); |
| return bool==null?false:bool.booleanValue(); |
| } |
| return isAccessible; |
| }}); |
| return accessible==null?false:accessible.booleanValue(); |
| } |
| }; |
| |
| /** |
| * {@link Session} service implementation for anonymous user |
| */ |
| final class SensiNactAnonymousSession extends SensiNactSession implements AnonymousSession { |
| |
| /** |
| * Constructor |
| * |
| * @param identifier |
| * the String identifier of the Session to be created |
| */ |
| SensiNactAnonymousSession(String identifier) { |
| super(identifier); |
| } |
| |
| @Override |
| public final void registerUser(final String login, final String password, final String account, final String accountType) |
| throws SecuredAccessException { |
| SecuredAccessException exception = SensiNact.this.mediator.callService( |
| UserManager.class, new Executable<UserManager,SecuredAccessException>(){ |
| @Override |
| public SecuredAccessException execute(UserManager userManager) throws Exception { |
| try { |
| if(userManager.accountExists(account)||userManager.loginExists(login)) { |
| throw new SecuredAccessException("A user with this login or account already exists"); |
| } |
| final String token = SensiNact.this.nextToken(); |
| final UserUpdater userUpdater = userManager.createUser(token, login, password, account, accountType); |
| |
| ServiceReference[] references = SensiNact.this.mediator.getContext().getServiceReferences( |
| AccountConnector.class.getName(), new StringBuilder().append("(org.eclipse.sensinact.security.account.type=" |
| ).append(accountType).append(")").toString()); |
| |
| if(references == null || references.length == 0){ |
| throw new SecuredAccessException("No account connector"); |
| } |
| int index = 0; |
| for(;index < references.length;index++) { |
| AccountConnector connector = (AccountConnector)SensiNact.this.mediator.getContext( |
| ).getService(references[index]); |
| if(connector != null) { |
| connector.connect(token, userUpdater); |
| SensiNact.this.mediator.getContext().ungetService(references[index]); |
| break; |
| } |
| } |
| } catch(SecuredAccessException e) { |
| return e; |
| } catch(Exception e) { |
| return new SecuredAccessException(e); |
| } |
| return null; |
| } |
| } |
| ); |
| if(exception != null) { |
| throw exception; |
| } |
| } |
| |
| @Override |
| public final void renewPassword(final String account) throws SecuredAccessException { |
| SecuredAccessException exception = SensiNact.this.mediator.callService( |
| UserManager.class, new Executable<UserManager,SecuredAccessException>(){ |
| @Override |
| public SecuredAccessException execute(UserManager userManager) throws Exception { |
| User user = userManager.getUserFromAccount(account); |
| if(user==null) { |
| return new SecuredAccessException("No user found for this account"); |
| } |
| try{ |
| final String token = SensiNact.this.nextToken(); |
| final UserUpdater userUpdater = userManager.renewUserPassword(token, account, user.getAccountType()); |
| |
| ServiceReference[] references = SensiNact.this.mediator.getContext().getServiceReferences( |
| AccountConnector.class.getName(), new StringBuilder().append("(org.eclipse.sensinact.security.account.type=" |
| ).append(user.getAccountType()).append(")").toString()); |
| |
| if(references == null || references.length == 0){ |
| return new SecuredAccessException("No account connector"); |
| } |
| int index = 0; |
| for(;index < references.length;index++) { |
| AccountConnector connector = (AccountConnector)SensiNact.this.mediator.getContext( |
| ).getService(references[index]); |
| if(connector != null) { |
| connector.connect(token, userUpdater); |
| SensiNact.this.mediator.getContext().ungetService(references[index]); |
| break; |
| } |
| } |
| } catch(SecuredAccessException e) { |
| return e; |
| } catch(Exception e) { |
| return new SecuredAccessException(e); |
| } |
| return null; |
| } |
| } |
| ); |
| if(exception != null) { |
| throw exception; |
| } |
| } |
| } |
| |
| /** |
| * {@link Session} service implementation for authenticated user |
| */ |
| final class SensiNactAuthenticatedSession extends SensiNactSession implements AuthenticatedSession { |
| |
| /** |
| * Constructor |
| * |
| * @param identifier the String identifier of the Session to be created |
| */ |
| SensiNactAuthenticatedSession(String identifier) { |
| super(identifier); |
| } |
| |
| @Override |
| public final void changePassword(final String oldPassword, final String newPassword) throws SecuredAccessException { |
| final SessionKey sessionKey; |
| synchronized(SensiNact.this.sessions) { |
| sessionKey = SensiNact.this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, |
| getSessionId())); |
| } |
| final String publicKey = sessionKey.getPublicKey(); |
| |
| SecuredAccessException exception = SensiNact.this.mediator.callService( |
| UserManager.class, new Executable<UserManager,SecuredAccessException>(){ |
| @Override |
| public SecuredAccessException execute(UserManager userManager) throws Exception { |
| User user = userManager.getUserFromPublicKey(publicKey); |
| try { |
| String encryptedPassword = CryptoUtils.cryptWithMD5(oldPassword); |
| userManager.updateField(user, "password", encryptedPassword, newPassword); |
| } catch(SecuredAccessException e){ |
| return e; |
| }catch(Exception e){ |
| return new SecuredAccessException(e); |
| } |
| return null; |
| } |
| } |
| ); |
| } |
| } |
| |
| // ********************************************************************// |
| // ABSTRACT DECLARATIONS // |
| // ********************************************************************// |
| |
| // ********************************************************************// |
| // STATIC DECLARATIONS // |
| // ********************************************************************// |
| private static final Logger LOG=LoggerFactory.getLogger(SensiNact.class); |
| protected static final int LOCAL_ID = 0; |
| |
| private static String getUri(boolean resolved, String namespace, String... pathElements) { |
| if (pathElements == null || pathElements.length == 0) { |
| return null; |
| } |
| String providerId = resolved |
| ? new StringBuilder().append(namespace).append(":").append(pathElements[0]).toString() |
| : pathElements[0]; |
| |
| String[] uriElements = new String[pathElements.length]; |
| if (pathElements.length > 1) { |
| System.arraycopy(pathElements, 1, uriElements, 1, pathElements.length - 1); |
| } |
| uriElements[0] = providerId; |
| return UriUtils.getUri(uriElements); |
| } |
| |
| private static <T, R extends AccessMethodResponse<T>> R createErrorResponse(Mediator mediator, String type, |
| String uri, int statusCode, String message, Exception e) { |
| R response = AccessMethodResponse.<T, R>error(mediator, uri, AccessMethod.Type.valueOf(type), statusCode, |
| message, e); |
| return response; |
| } |
| |
| private static <T, R extends DescribeResponse<T>> R createErrorResponse(Mediator mediator, |
| DescribeMethod.DescribeType type, String uri, int statusCode, String message, Exception e) { |
| R response = AccessMethodResponse.<T, R>error(mediator, uri, type, statusCode, message, e); |
| return response; |
| } |
| |
| // ********************************************************************// |
| // INSTANCE DECLARATIONS // |
| // ********************************************************************// |
| |
| private final Sessions sessions; |
| private AccessTree<? extends AccessNode> anonymousTree; |
| |
| public Mediator mediator; |
| private RegistryEndpoint registry; |
| |
| private volatile AtomicInteger count = new AtomicInteger(LOCAL_ID + 1); |
| |
| private final <R, P> R doPrivilegedService(final Class<P> p, final String f, final Executable<P, R> e) { |
| R r = AccessController.<R>doPrivileged(new PrivilegedAction<R>() { |
| @Override |
| public R run() { |
| return mediator.callService(p, f, e); |
| } |
| }); |
| return r; |
| } |
| |
| private final <P> Void doPrivilegedVoidServices(final Class<P> p, final String f, final Executable<P, Void> e) { |
| return AccessController.<Void>doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| mediator.<P>callServices(p, f, e); |
| return null; |
| } |
| }); |
| } |
| |
| private final AccessTree<?> getAnonymousTree() { |
| AccessTree<?> tree = null; |
| if (MutableAccessTree.class.isAssignableFrom(this.anonymousTree.getClass())) { |
| tree = ((MutableAccessTree<?>) this.anonymousTree).clone(); |
| } else { |
| tree = this.anonymousTree; |
| } |
| return tree; |
| } |
| |
| public final AccessTree<?> getUserAccessTree(final String publicKey) { |
| AccessTree<? extends AccessNode> tree = null; |
| if (publicKey != null && !publicKey.startsWith(UserManager.ANONYMOUS_PKEY)) { |
| tree = doPrivilegedService(SecuredAccess.class, null, |
| new Executable<SecuredAccess, AccessTree<? extends AccessNode>>() { |
| @Override |
| public AccessTree<? extends AccessNode> execute(SecuredAccess securedAccess) throws Exception { |
| AccessTree<? extends AccessNode> tree = securedAccess.getUserAccessTree(publicKey); |
| return tree; |
| } |
| }); |
| } |
| if (tree == null) { |
| tree = getAnonymousTree(); |
| } |
| return tree; |
| } |
| |
| // @Reference |
| // private ConditionalPermissionAdmin cpa; |
| |
| public SensiNact() { |
| this.sessions = new Sessions(); |
| } |
| |
| @Activate |
| public void activate(ComponentContext context) throws SecuredAccessException, |
| BundleException, DataStoreException { |
| |
| Mediator mediator = new Mediator(context.getBundleContext()); |
| // List<String> types = ReflectUtils.getAllStringTypes(mediator.getContext().getBundle()); |
| // |
| // StringBuilder builder = new StringBuilder(); |
| // |
| // for (int index = 0; index < types.size(); index++) { |
| // if (index > 0) |
| // builder.append("\\,"); |
| // builder.append(types.get(index)); |
| // } |
| // |
| // ConditionalPermissionUpdate cpu = cpa.newConditionalPermissionUpdate(); |
| // List piList = cpu.getConditionalPermissionInfos(); |
| // |
| // ConditionalPermissionInfo cpiDeny = cpa.newConditionalPermissionInfo( |
| // String.format("DENY { [org.eclipse.sensinact.gateway.core.security.perm.StrictCodeBaseCondition \"%s\" \"!\"]" |
| // + " (org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.Core\" \"register\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.SensiNactResourceModel\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.SensiNactResourceModelElement\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.message.LocalAgent\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.message.RemoteAgent\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.remote.RemoteCore\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.security.SecuredAccess\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.security.UserManager\" \"register,get\")" |
| // + "(org.osgi.framework.ServicePermission \"org.eclipse.sensinact.gateway.core.security.SecurityDataStoreService\" \"register,get\")" |
| // + "} null", builder.toString())); |
| // piList.add(cpiDeny); |
| |
| // ConditionalPermissionInfo cpiAllow = null;" |
| // |
| // cpiAllow = cpa.newConditionalPermissionInfo( |
| // "ALLOW {[org.eclipse.sensinact.gateway.core.security.perm.CodeBaseCondition \"*\"](java.security.AllPermission \"\" \"\")} null"); |
| // |
| // piList.add(cpiAllow); |
| // |
| // if (!cpu.commit()) |
| // throw new ConcurrentModificationException("Permissions changed during update"); |
| // |
| SecuredAccess securedAccess = null; |
| ServiceLoader<SecurityDataStoreServiceFactory> dataStoreServiceFactoryLoader = |
| ServiceLoader.load(SecurityDataStoreServiceFactory.class, mediator.getClassLoader()); |
| |
| Iterator<SecurityDataStoreServiceFactory> dataStoreServiceFactoryIterator = |
| dataStoreServiceFactoryLoader.iterator(); |
| |
| if (dataStoreServiceFactoryIterator.hasNext()) { |
| SecurityDataStoreServiceFactory<?> factory = dataStoreServiceFactoryIterator.next(); |
| if (factory != null) |
| factory.newInstance(mediator); |
| } |
| ServiceLoader<UserManagerFactory> userManagerFactoryLoader = ServiceLoader.load( |
| UserManagerFactory.class, mediator.getClassLoader()); |
| |
| Iterator<UserManagerFactory> userManagerFactoryIterator = userManagerFactoryLoader.iterator(); |
| |
| while (userManagerFactoryIterator.hasNext()) { |
| UserManagerFactory factory = userManagerFactoryIterator.next(); |
| if (factory != null) { |
| factory.newInstance(mediator); |
| break; |
| } |
| } |
| ServiceLoader<SecuredAccessFactory> securedAccessFactoryLoader = ServiceLoader.load( |
| SecuredAccessFactory.class, mediator.getClassLoader()); |
| |
| Iterator<SecuredAccessFactory> securedAccessFactoryIterator = securedAccessFactoryLoader.iterator(); |
| |
| while (securedAccessFactoryIterator.hasNext()) { |
| SecuredAccessFactory factory = securedAccessFactoryIterator.next(); |
| if (factory != null) { |
| securedAccess = factory.newInstance(mediator); |
| break; |
| } |
| } |
| if (securedAccess == null) |
| throw new BundleException("A SecuredAccess service was excepted"); |
| |
| securedAccess.createAuthorizationService(); |
| final SecuredAccess sa = securedAccess; |
| |
| AccessController.doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| mediator.register(sa, SecuredAccess.class, null); |
| return null; |
| } |
| }); |
| this.anonymousTree = mediator.callService(SecuredAccess.class, |
| new Executable<SecuredAccess, AccessTree<? extends AccessNode>>() { |
| @Override |
| public AccessTree<? extends AccessNode> execute(SecuredAccess securedAccess) throws Exception { |
| return securedAccess.getUserAccessTree(UserManager.ANONYMOUS_PKEY); |
| } |
| } |
| ); |
| this.mediator = mediator; |
| this.registry = new RegistryEndpoint(mediator); |
| |
| ServiceLoader<SensinactCoreBaseIFaceManagerFactory> loader = ServiceLoader.load( |
| SensinactCoreBaseIFaceManagerFactory.class, mediator.getClassLoader()); |
| |
| Iterator<SensinactCoreBaseIFaceManagerFactory> it = loader.iterator(); |
| |
| while(it.hasNext()){ |
| SensinactCoreBaseIFaceManagerFactory factory = it.next(); |
| SensinactCoreBaseIFaceManager manager = factory.instance(); |
| if(manager!=null) { |
| manager.start(mediator); |
| break; |
| } |
| } |
| } |
| |
| @Deactivate |
| public void deactivate() { |
| this.close(); |
| } |
| // |
| // |
| // |
| // /** |
| // * Constructor |
| // * |
| // * @param mediator |
| // * the extended {@link Mediator} allowing the {@link Core} to be |
| // * instantiated to interact with the OSGi host environment |
| // * |
| // * @throws SecuredAccessException |
| // * @throws BundleException |
| // */ |
| // public SensiNact(final Mediator mediator) throws SecuredAccessException, BundleException, DataStoreException { |
| // |
| // SecuredAccess securedAccess = null; |
| // ServiceLoader<SecurityDataStoreServiceFactory> dataStoreServiceFactoryLoader = |
| // ServiceLoader.load(SecurityDataStoreServiceFactory.class, mediator.getClassLoader()); |
| // |
| // Iterator<SecurityDataStoreServiceFactory> dataStoreServiceFactoryIterator = |
| // dataStoreServiceFactoryLoader.iterator(); |
| // |
| // if (dataStoreServiceFactoryIterator.hasNext()) { |
| // SecurityDataStoreServiceFactory<?> factory = dataStoreServiceFactoryIterator.next(); |
| // if (factory != null) { |
| // factory.newInstance(mediator); |
| // } |
| // } |
| // ServiceLoader<UserManagerFactory> userManagerFactoryLoader = ServiceLoader.load( |
| // UserManagerFactory.class, mediator.getClassLoader()); |
| // |
| // Iterator<UserManagerFactory> userManagerFactoryIterator = userManagerFactoryLoader.iterator(); |
| // |
| // while (userManagerFactoryIterator.hasNext()) { |
| // UserManagerFactory factory = userManagerFactoryIterator.next(); |
| // if (factory != null) { |
| // factory.newInstance(mediator); |
| // break; |
| // } |
| // } |
| // ServiceLoader<SecuredAccessFactory> securedAccessFactoryLoader = ServiceLoader.load( |
| // SecuredAccessFactory.class, mediator.getClassLoader()); |
| // |
| // Iterator<SecuredAccessFactory> securedAccessFactoryIterator = securedAccessFactoryLoader.iterator(); |
| // |
| // while (securedAccessFactoryIterator.hasNext()) { |
| // SecuredAccessFactory factory = securedAccessFactoryIterator.next(); |
| // if (factory != null) { |
| // securedAccess = factory.newInstance(mediator); |
| // break; |
| // } |
| // } |
| // if (securedAccess == null) { |
| // throw new BundleException("A SecuredAccess service was excepted"); |
| // } |
| // securedAccess.createAuthorizationService(); |
| // final SecuredAccess sa = securedAccess; |
| // |
| // AccessController.doPrivileged(new PrivilegedAction<Void>() { |
| // @Override |
| // public Void run() { |
| // mediator.register(sa, SecuredAccess.class, null); |
| // return null; |
| // } |
| // }); |
| // this.defaultLocation = ModelInstance.defaultLocation(mediator); |
| // this.sessions = new Sessions(); |
| // |
| // this.anonymousTree = mediator.callService(SecuredAccess.class, |
| // new Executable<SecuredAccess, AccessTree<? extends AccessNode>>() { |
| // @Override |
| // public AccessTree<? extends AccessNode> execute(SecuredAccess securedAccess) throws Exception { |
| // return securedAccess.getUserAccessTree(UserManager.ANONYMOUS_PKEY); |
| // } |
| // }); |
| // this.mediator = mediator; |
| // this.registry = new RegistryEndpoint(mediator); |
| // |
| // ServiceLoader<SensinactCoreBaseIFaceManagerFactory> loader = ServiceLoader.load( |
| // SensinactCoreBaseIFaceManagerFactory.class, mediator.getClassLoader()); |
| // |
| // Iterator<SensinactCoreBaseIFaceManagerFactory> it = loader.iterator(); |
| // |
| // while(it.hasNext()){ |
| // SensinactCoreBaseIFaceManagerFactory factory = it.next(); |
| // SensinactCoreBaseIFaceManager manager = factory.instance(); |
| // if(manager!=null) { |
| // manager.start(mediator); |
| // break; |
| // } |
| // } |
| // } |
| |
| @Override |
| public AuthenticatedSession getSession(final Authentication<?> authentication) |
| throws InvalidKeyException, InvalidCredentialException { |
| AuthenticatedSession session = null; |
| if (authentication == null) { |
| return null; |
| |
| } else if (Credentials.class.isAssignableFrom(authentication.getClass())) { |
| UserKey userKey = this.doPrivilegedService(AuthenticationService.class, null, |
| new Executable<AuthenticationService, UserKey>() { |
| @Override |
| public UserKey execute(AuthenticationService service) throws Exception { |
| return service.buildKey((Credentials) authentication); |
| } |
| }); |
| if (userKey == null) { |
| throw new InvalidCredentialException("Invalid credentials"); |
| } |
| String pkey = userKey.getPublicKey(); |
| AccessTree<? extends AccessNode> tree = this.getUserAccessTree(pkey); |
| SessionKey sessionKey = new SessionKey(mediator, LOCAL_ID, SensiNact.this.nextToken(), tree, null); |
| sessionKey.setUserKey(userKey); |
| session = new SensiNactAuthenticatedSession(sessionKey.getToken()); |
| synchronized(this.sessions) { |
| sessions.put(sessionKey, session); |
| } |
| } else if (AuthenticationToken.class.isAssignableFrom(authentication.getClass())) { |
| session = this.getSession(((AuthenticationToken) authentication).getAuthenticationMaterial()); |
| } |
| return session; |
| } |
| |
| @Override |
| public AuthenticatedSession getSession(final String token) { |
| AuthenticatedSession session; |
| synchronized(this.sessions){ |
| session= (AuthenticatedSession) this.sessions.getSessionFromToken(token); |
| } |
| return session; |
| } |
| |
| @Override |
| public Session getRemoteSession(final String publicKey) { |
| final int sessionCount; |
| synchronized(this.count) { |
| sessionCount = count.incrementAndGet(); |
| } |
| Session session = null; |
| String filteredKey = publicKey; |
| Class<? extends Session> sessionClass = null; |
| |
| if (publicKey.startsWith(UserManager.ANONYMOUS_PKEY)) { |
| filteredKey = new StringBuilder().append(publicKey).append("_remote" |
| ).append(sessionCount).toString(); |
| sessionClass = SensiNactAnonymousSession.class; |
| } else { |
| sessionClass = SensiNactAuthenticatedSession.class; |
| } |
| final String sessionToken; |
| synchronized(SensiNact.this.count) { |
| sessionToken = SensiNact.this.nextToken(); |
| } |
| AccessTree<? extends AccessNode> tree = SensiNact.this.getUserAccessTree(filteredKey); |
| SessionKey sessionKey = new SessionKey(mediator, sessionCount, sessionToken, tree, null); |
| sessionKey.setUserKey(new UserKey(filteredKey)); |
| try { |
| session = sessionClass.getDeclaredConstructor( |
| new Class<?>[] { SensiNact.class, String.class }).newInstance( |
| new Object[] { SensiNact.this, sessionKey.getToken() }); |
| synchronized(SensiNact.this.sessions) { |
| SensiNact.this.sessions.put(sessionKey, session); |
| } |
| } catch (Exception e) { |
| mediator.error(e); |
| } |
| return session; |
| } |
| |
| @Override |
| public AnonymousSession getAnonymousSession() { |
| int sessionCount = -1; |
| String sessionToken = null; |
| |
| synchronized(count) { |
| sessionCount = count.incrementAndGet(); |
| sessionToken = this.nextToken(); |
| } |
| String pkey = new StringBuilder().append(UserManager.ANONYMOUS_PKEY).append( |
| "_").append(sessionCount).toString(); |
| SessionKey sessionKey = new SessionKey(mediator, LOCAL_ID, sessionToken, |
| this.getAnonymousTree(), null); |
| sessionKey.setUserKey(new UserKey(pkey)); |
| |
| AnonymousSession session = new SensiNactAnonymousSession(sessionToken); |
| synchronized(this.sessions) { |
| this.sessions.put(sessionKey, session); |
| } |
| return session; |
| } |
| |
| @Override |
| public Session getApplicationSession(final Mediator mediator, final String privateKey) { |
| |
| final int sessionCount; |
| final String sessionToken; |
| |
| synchronized(count) { |
| sessionCount = count.incrementAndGet(); |
| sessionToken = this.nextToken(); |
| } |
| SessionKey skey = this.doPrivilegedService(SecuredAccess.class, null, |
| new Executable<SecuredAccess, SessionKey>() { |
| @Override |
| public SessionKey execute(SecuredAccess securedAccess) throws Exception { |
| String publicKey = securedAccess.getApplicationPublicKey(privateKey); |
| AccessTree<? extends AccessNode> tree = null; |
| if (publicKey == null) { |
| publicKey = new StringBuilder().append(UserManager.ANONYMOUS_PKEY |
| ).append("_").append(sessionCount).toString(); |
| tree = SensiNact.this.getAnonymousTree(); |
| } else { |
| tree = securedAccess.getApplicationAccessTree(publicKey); |
| } |
| SessionKey sessionKey = new SessionKey(mediator, LOCAL_ID, |
| sessionToken, tree, null); |
| |
| sessionKey.setUserKey(new UserKey(publicKey)); |
| return sessionKey; |
| } |
| }); |
| Session session = new SensiNactAuthenticatedSession(skey.getToken()); |
| synchronized(this.sessions) { |
| sessions.put(skey, session); |
| } |
| return session; |
| } |
| |
| @Override |
| public String namespace() { |
| return this.registry.namespace(); |
| } |
| |
| @Override |
| public String registerAgent(final Mediator mediator, final MidAgentCallback callback, final SnaFilter filter) { |
| String agentKey = getAccessKey(mediator); |
| final LocalAgent agent = LocalAgentImpl.createAgent(mediator, callback, filter, agentKey); |
| AccessController.<Void>doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| agent.start(); |
| return null; |
| } |
| }); |
| return callback.getName(); |
| } |
| |
| //Retrieves the access key attaches to a specific bundle and agent |
| private String getAccessKey(Mediator mediator) { |
| final Bundle bundle = mediator.getContext().getBundle(); |
| |
| final String bundleIdentifier = this.doPrivilegedService(BundleValidation.class, null, |
| new Executable<BundleValidation, String>() { |
| @Override |
| public String execute(BundleValidation bundleValidation) throws Exception { |
| return bundleValidation.check(bundle); |
| } |
| }); |
| String publicKey = this.doPrivilegedService(SecuredAccess.class, null, |
| new Executable<SecuredAccess, String>() { |
| @Override |
| public String execute(SecuredAccess securedAccess) throws Exception { |
| return securedAccess.getAgentPublicKey(bundleIdentifier); |
| } |
| }); |
| return publicKey; |
| } |
| |
| //builds an AthenticatedSession based on the String public key passed as parameter |
| private Session buildLocalSessionFromPublicKey(String publicKey) { |
| Session session = null; |
| Class<? extends Session> sessionClass = null; |
| String sessionToken; |
| int sessionCount; |
| |
| synchronized(count) { |
| sessionCount = count.incrementAndGet(); |
| sessionToken = this.nextToken(); |
| } |
| AccessTree<? extends AccessNode> tree = SensiNact.this.getUserAccessTree(publicKey); |
| SessionKey sessionKey = new SessionKey(mediator, LOCAL_ID, sessionToken, tree, null); |
| sessionKey.setUserKey(new UserKey(publicKey)); |
| |
| try { |
| session = new SensiNactAuthenticatedSession(sessionKey.getToken()); |
| synchronized(SensiNact.this.sessions) { |
| SensiNact.this.sessions.put(sessionKey, session); |
| } |
| } catch (Exception e) { |
| mediator.error(e); |
| } |
| return session; |
| } |
| |
| @Override |
| public String registerIntent(Mediator mediator, Executable<Boolean,Void> onAccessible, final String... path) { |
| |
| final Bundle bundle = mediator.getContext().getBundle(); |
| |
| final String bundleIdentifier = this.doPrivilegedService(BundleValidation.class, null, |
| new Executable<BundleValidation, String>() { |
| @Override |
| public String execute(BundleValidation bundleValidation) throws Exception { |
| return bundleValidation.check(bundle); |
| } |
| }); |
| final String intentKey = this.doPrivilegedService(SecuredAccess.class, null, |
| new Executable<SecuredAccess, String>() { |
| @Override |
| public String execute(SecuredAccess securedAccess) throws Exception { |
| return securedAccess.getAgentPublicKey(bundleIdentifier); |
| } |
| }); |
| final ResourceIntent intent = new ResourceIntent(mediator, intentKey, onAccessible, path) { |
| @Override |
| public boolean isAccessible(String path) { |
| return SensiNact.this.isAccessible(this.getPublicKey(), path); |
| } |
| |
| @Override |
| public String namespace() { |
| return SensiNact.this.namespace(); |
| } |
| }; |
| AccessController.<Void>doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| intent.start(); |
| return null; |
| } |
| }); |
| return intent.getName(); |
| } |
| |
| /** |
| * Unregisters the {@link SnaAgent} whose identifier is passed as parameter |
| * |
| * @param identifier the identifier of the {@link SnaAgent} to register |
| */ |
| public void unregisterAgent(final String identifier) { |
| doPrivilegedService(SnaAgent.class, |
| String.format("(org.eclipse.sensinact.gateway.agent.id=%s",identifier), |
| new Executable<SnaAgent, Void>() { |
| @Override |
| public Void execute(SnaAgent agent) throws Exception { |
| agent.stop(); |
| return null; |
| } |
| } |
| ); |
| } |
| |
| /** |
| * Returns the Set of available {@link ServiceProvider}s compliant to the LDAP |
| * formated filter passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the list of |
| * available service providers |
| * @param filter |
| * the String LDAP formated filter |
| * |
| * @return the Set of available {@link ServiceProvider}s compliant to the |
| * specified filter and for the specified {@link Session} |
| */ |
| protected Set<ServiceProvider> serviceProviders(String identifier, String filter) { |
| SessionKey sessionKey; |
| synchronized(this.sessions) { |
| sessionKey = this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN,identifier)); |
| } |
| Set<ServiceProvider> set = new HashSet<ServiceProvider>(); |
| set.addAll(this.registry.serviceProviders(sessionKey, filter)); |
| return set; |
| } |
| |
| /** |
| * Returns the {@link ServiceProvider} whose String identifier is passed as parameter |
| * |
| * @param identifier the String identifier of the {@link Session} requiring the service provider |
| * @param serviceProviderId the String identifier of the service provider |
| * |
| * @return the {@link ServiceProvider} |
| */ |
| protected ServiceProvider serviceProvider(String identifier, String serviceProviderId) { |
| SessionKey sessionKey; |
| synchronized(this.sessions) { |
| sessionKey = this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN,identifier)); |
| } |
| return this.registry.serviceProvider(sessionKey, serviceProviderId); |
| } |
| |
| /** |
| * Returns the {@link Service} whose String identifier is passed as parameter, |
| * held by the specified service provider |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the service |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * @param serviceId |
| * the String identifier of the service |
| * |
| * @return the {@link Service} |
| */ |
| protected Service service(String identifier, String serviceProviderId, String serviceId) { |
| SessionKey sessionKey; |
| synchronized(this.sessions) { |
| sessionKey = this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN,identifier)); |
| } |
| return this.registry.service(sessionKey, serviceProviderId, serviceId); |
| } |
| |
| /** |
| * Returns the {@link Resource} whose String identifier is passed as parameter, |
| * held by the specified service provider and service |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the |
| * resource |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * providing the resource |
| * @param serviceId |
| * the String identifier of the service providing the resource |
| * @param resourceId |
| * the String identifier of the resource |
| * |
| * @return the {@link Resource} |
| */ |
| protected Resource resource(String identifier, String serviceProviderId, String serviceId, String resourceId) { |
| SessionKey sessionKey; |
| synchronized(this.sessions) { |
| sessionKey = this.sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN,identifier)); |
| } |
| return this.registry.resource(sessionKey, serviceProviderId, serviceId, resourceId); |
| } |
| |
| /** |
| * Returns true if the model element targeted by the String path argument |
| * exists and is accessible to the {@link Session} whose {@link SessionKey} |
| * is also passed as parameter. Returns false if the model element does not |
| * exist or is not accessible to the {@link Session} |
| * |
| * @param sessionKey the {@link SessionKey} of the {@link Session} for which to |
| * define the targeted model element accessibility |
| * @param path the String path of the targeted model element |
| * |
| * @return |
| * <ul> |
| * <li>true if the targeted model element exists and is accessible to the |
| * specified {@link Session}</li> |
| * <li>false otherwise</li> |
| * </ul> |
| */ |
| protected boolean isAccessible(final SessionKey sessionKey , final String path) { |
| return isAccessible(sessionKey.getPublicKey(),sessionKey.getAccessTree(),path); |
| } |
| |
| /** |
| * Returns true if the model element targeted by the String path argument |
| * exists and is accessible to the user whose String public key |
| * is also passed as parameter. Returns false if the model element does not |
| * exist or is not accessible to the {@link Session} |
| * |
| * @param publicKey the String public key of the user for which to |
| * define the targeted model element accessibility |
| * @param path the String path of the targeted model element |
| * |
| * @return |
| * <ul> |
| * <li>true if the targeted model element exists and is accessible to the |
| * specified user</li> |
| * <li>false otherwise</li> |
| * </ul> |
| */ |
| public boolean isAccessible(final String publicKey , final String path) { |
| return isAccessible(publicKey, getUserAccessTree(publicKey),path); |
| } |
| |
| /** |
| * Returns true if the model element targeted by the String path argument |
| * exists and is accessible to the user whose String public key and {@link AccessTree} |
| * are also passed as parameters. Returns false if the model element does not |
| * exist or is not accessible to the {@link Session} |
| * |
| * @param publicKey the String public key of the user for which to |
| * define the targeted model element accessibility |
| * @param tree the {@link AccessTree} of the user for which to |
| * define the targeted model element accessibility |
| * @param path the String path of the targeted model element |
| * |
| * @return |
| * <ul> |
| * <li>true if the targeted model element exists and is accessible to the |
| * specified user</li> |
| * <li>false otherwise</li> |
| * </ul> |
| */ |
| protected boolean isAccessible(final String publicKey, AccessTree<?> tree, final String path) { |
| String[] uriElements = UriUtils.getUriElements(path); |
| String[] providerElements = uriElements[0].split(":"); |
| String[] uri = new String[uriElements.length]; |
| |
| if(uriElements.length > 1) |
| System.arraycopy(uriElements, 1, uri, 1, uriElements.length -1); |
| |
| uri[0] = providerElements.length > 1?providerElements[1]:providerElements[0]; |
| return this.registry.isAccessible(tree, UriUtils.getUri(uri)); |
| } |
| |
| /** |
| * Executes the {@link Executable} passed as parameter which expects a |
| * {@link RemoteCore} parameter, and returns its JSON formated execution result |
| * |
| * @param serviceProviderId |
| * the String identifier of the service provider whose prefix allows |
| * to identified the targeted {@link RemoteCore} |
| * @param executable |
| * the {@link Executable} to be executed |
| * |
| * @return the JSON formated result of the {@link Executable} execution |
| */ |
| private <F> F remoteCoreInvocation(String serviceProviderId, Executable<SensinactCoreBaseIface, F> executable) { |
| String[] serviceProviderIdElements = serviceProviderId.split(":"); |
| String remoteNamespace = serviceProviderIdElements[0]; |
| F f = null; |
| if (serviceProviderIdElements.length == 1 || remoteNamespace.length() == 0 || remoteNamespace.equals(this.namespace()) ) |
| return f; |
| f = mediator.callService(SensinactCoreBaseIface.class, String.format("(%s=%s)", |
| SensinactCoreBaseIFaceManager.REMOTE_NAMESPACE_PROPERTY, remoteNamespace), executable); |
| return f; |
| } |
| |
| /** |
| * Invokes the ACT access method on the resource whose String identifier is |
| * passed as parameter, held by the specified service provider and service |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} invoking the access |
| * method |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * providing the resource on which applies the access method call |
| * @param serviceId |
| * the String identifier of the service providing the resource on |
| * which applies the access method call |
| * @param resourceId |
| * the String identifier of the resource on which applies the access |
| * method call |
| * @param parameters |
| * the Objects array parameterizing the call |
| * |
| * @return the JSON formated response of the ACT access method invocation |
| */ |
| private JSONObject act(String identifier, final String serviceProviderId, final String serviceId, |
| final String resourceId, final Object[] parameters) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| String response = remoteCoreInvocation(serviceProviderId, new RemoteAccessMethodExecutable( |
| mediator, |
| AccessMethod.Type.valueOf(AccessMethod.ACT), sessionKey.getPublicKey( |
| )).withServiceProvider(serviceProviderId |
| ).withService(serviceId |
| ).withResource(resourceId |
| ).with(RemoteAccessMethodExecutable.ARGUMENTS_TK, parameters)); |
| JSONObject object = new JSONObject(response); |
| return object; |
| } |
| |
| /** |
| * Invokes the SET access method on the resource whose String identifier is |
| * passed as parameter, held by the specified service provider and service |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} invoking the access |
| * method |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * providing the resource on which applies the access method call |
| * @param serviceId |
| * the String identifier of the service providing the resource on |
| * which applies the access method call |
| * @param resourceId |
| * the String identifier of the resource on which applies the access |
| * method call |
| * @param attributeId |
| * the String identifier of the resource's attribute targeted by the |
| * access method call |
| * @param parameter |
| * the value object to be set |
| * |
| * @return the JSON formated response of the SET access method invocation |
| */ |
| private JSONObject set(String identifier, final String serviceProviderId, final String serviceId, |
| final String resourceId, final String attributeId, final Object parameter) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| String response = remoteCoreInvocation(serviceProviderId, |
| new RemoteAccessMethodExecutable(mediator, AccessMethod.Type.valueOf(AccessMethod.SET |
| ), sessionKey.getPublicKey() |
| ).withServiceProvider(serviceProviderId |
| ).withService(serviceId |
| ).withResource(resourceId |
| ).withAttribute(attributeId |
| ).with(RemoteAccessMethodExecutable.VALUE_TK, parameter)); |
| JSONObject object = new JSONObject(response); |
| return object; |
| } |
| |
| private boolean match(String expected, String found) { |
| if(expected == null) |
| return true; |
| if(found == null) |
| return false; |
| if(found.equals(expected)) |
| return true; |
| if(!expected.startsWith("(") || !expected.endsWith(")")) |
| return false; |
| String pattern = expected.substring(1,expected.length()-1); |
| boolean match = true; |
| if(pattern.startsWith("*")) { |
| int pos = found.length()-1; |
| for(int i=pattern.length()-1;i>0;i--) { |
| if(pattern.charAt(i)!=found.charAt(pos)) { |
| match=false; |
| break; |
| } |
| pos--; |
| } |
| } else if(pattern.endsWith("*")){ |
| int pos = 0; |
| for(int i=0;i<pattern.length()-1;i++) { |
| if(pattern.charAt(i)!=found.charAt(pos)) { |
| match=false; |
| break; |
| } |
| pos++; |
| } |
| } else { |
| try { |
| Pattern _pattern = Pattern.compile(pattern); |
| match = _pattern.matcher(found).matches(); |
| } catch(Exception e) { |
| match = false; |
| } |
| } |
| return match; |
| } |
| |
| /** |
| * Invokes the GET access method on the resource whose String identifier is |
| * passed as parameter, held by the specified service provider and service |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} invoking the access |
| * method |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * providing the resource on which applies the access method call |
| * @param serviceId |
| * the String identifier of the service providing the resource on |
| * which applies the access method call |
| * @param resourceId |
| * the String identifier of the resource on which applies the access |
| * method call |
| * @param attributeId |
| * the String identifier of the resource's attribute targeted by the |
| * access method call |
| * |
| * @return the JSON formated response of the GET access method invocation |
| */ |
| private JSONObject get(String identifier, final String serviceProviderId, final String serviceId, |
| final String resourceId, final String attributeId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| if(serviceProviderId.indexOf('(') < 0) { |
| String response = remoteCoreInvocation(serviceProviderId, |
| new RemoteAccessMethodExecutable(mediator, AccessMethod.Type.valueOf(AccessMethod.GET |
| ), sessionKey.getPublicKey() |
| ).withServiceProvider(serviceProviderId |
| ).withService(serviceId |
| ).withResource(resourceId |
| ).withAttribute(attributeId)); |
| JSONObject object = null; |
| if(response != null) |
| object = new JSONObject(response); |
| return object; |
| } |
| List<Future<String>> results = new ArrayList<Future<String>>(); |
| ExecutorService executor = Executors.newFixedThreadPool(20); |
| |
| if (sessionKey.localID() == 0) { |
| Collection<ServiceReference<SensinactCoreBaseIface>> references = null; |
| try { |
| references = mediator.getContext().getServiceReferences(SensinactCoreBaseIface.class, String.format("(!(%s=%s))", |
| SensinactCoreBaseIFaceManager.REMOTE_NAMESPACE_PROPERTY,namespace())); |
| } catch (InvalidSyntaxException e) { |
| mediator.debug(e.getMessage()); |
| } |
| if(references!=null) { |
| for (ServiceReference<SensinactCoreBaseIface> reference : references) { |
| final SensinactCoreBaseIface core; |
| if (reference == null || (core = mediator.getContext().getService(reference)) == null) |
| continue; |
| results.add(executor.submit(new Callable<String>() { |
| @Override |
| public String call() throws Exception { |
| return core.get(sessionKey.getPublicKey(), serviceProviderId, serviceId, resourceId, attributeId); |
| } |
| })); |
| } |
| } |
| } |
| Collection<ServiceReference<SensiNactResourceModel>> modelReferences = this.registry.getReferences( |
| sessionKey.getAccessTree(), serviceProviderId); |
| try { |
| for (ServiceReference<SensiNactResourceModel> modelReference : modelReferences) { |
| SensiNactResourceModel resourceModel; |
| if (modelReference == null || (resourceModel = mediator.getContext().getService(modelReference)) == null) |
| continue; |
| |
| ServiceProvider p = null; |
| try { |
| p = ((ServiceProviderImpl) resourceModel.getRootElement()).<ServiceProvider>getProxy(sessionKey); |
| } catch (ModelElementProxyBuildException e) { |
| continue; |
| } |
| List<Service> services = p.getServices(); |
| for (Service s : services) { |
| if (s == null || !s.isAccessible()) |
| continue; |
| if(!match(serviceId,s.getName())) |
| continue; |
| List<Resource> resources = s.getResources(); |
| for (Resource r : resources) { |
| if (r == null || !r.isAccessible()) |
| continue; |
| if(!match(resourceId,r.getName())) |
| continue; |
| final Resource resource = r; |
| final Resource.Type type = resource.getType(); |
| if (attributeId == null && Resource.Type.ACTION.equals(type)) { |
| continue; |
| } |
| results.add(executor.submit(new Callable<String>() { |
| @Override |
| public String call() throws Exception { |
| if (attributeId == null) |
| return ((DataResource) resource).get().getJSON(); |
| return resource.get(attributeId).getJSON(); |
| } |
| })); |
| } |
| } |
| } |
| StringBuilder builder = new StringBuilder(); |
| String name = String.format("/%s/%s/%s/%s", serviceProviderId, |
| serviceId==null?"*":serviceId, |
| resourceId==null?"*":resourceId, |
| attributeId==null?"{default-attribute}":attributeId); |
| builder.append("{\"statusCode\":200,\"response\":{\"name\":\""); |
| builder.append(name); |
| builder.append("\",\"type\":\"array\",\"value\":["); |
| int index = 0; |
| for (Future<String> future : results) { |
| try { |
| String result = future.get(); |
| if (index > 0) |
| builder.append(","); |
| builder.append(result); |
| index++; |
| } catch (CancellationException | ExecutionException | InterruptedException e) { |
| continue; |
| } |
| } |
| builder.append("]}}"); |
| return new JSONObject(builder.toString()); |
| } finally { |
| for (ServiceReference<SensiNactResourceModel> modelReference : modelReferences) { |
| if (modelReference != null) |
| mediator.getContext().ungetService(modelReference); |
| } |
| } |
| } |
| |
| /** |
| * Returns the JSON formated description of the resource whose String identifier |
| * is passed as parameter, and held by the service provider and service whose |
| * String identifiers are also passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the |
| * resource description |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service, |
| * providing the resource |
| * @param serviceId |
| * the String identifier of the service providing the resource |
| * @param resourceId |
| * the String identifier of the resource to return the description of |
| * |
| * @return the JSON formated description of the specified resource |
| */ |
| private JSONObject getResource(String identifier, final String serviceProviderId, final String serviceId, final String resourceId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| final String localNamespace = this.namespace(); |
| JSONObject object = remoteCoreInvocation(serviceProviderId, new Executable<SensinactCoreBaseIface, JSONObject>() { |
| @Override |
| public JSONObject execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| return new JSONObject(core.getResource(sessionKey.getPublicKey(), |
| serviceProviderId.substring(serviceProviderId.indexOf(':') + 1), |
| serviceId, resourceId)); |
| } |
| }); |
| return object; |
| } |
| |
| /** |
| * Returns the JSON formated list of available resources, for the service and |
| * service provider whose String identifiers are passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the |
| * description |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * @param serviceId |
| * the String identifier of the service providing the resources |
| * |
| * @return the JSON formated list of available resources for the specified |
| * service and service provider |
| */ |
| private String getResources(String identifier, final String serviceProviderId, final String serviceId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| final String localNamespace = this.namespace(); |
| String object = remoteCoreInvocation(serviceProviderId, new Executable<SensinactCoreBaseIface, String>() { |
| @Override |
| public String execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| return core.getResources(sessionKey.getPublicKey(), serviceProviderId.substring( |
| serviceProviderId.indexOf(':') + 1), serviceId); |
| } |
| }); |
| return object; |
| } |
| |
| /** |
| * Returns the JSON formated description of the service whose String identifier |
| * is passed as parameter, and held by the specified service provider |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the service |
| * description |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the service |
| * @param serviceId |
| * the String identifier of the service to return the description of |
| * |
| * @return the JSON formated description of the specified service |
| */ |
| private JSONObject getService(String identifier, final String serviceProviderId, final String serviceId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| final String localNamespace = this.namespace(); |
| JSONObject object = remoteCoreInvocation(serviceProviderId, new Executable<SensinactCoreBaseIface, JSONObject>() { |
| @Override |
| public JSONObject execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| return new JSONObject(core.getService(sessionKey.getPublicKey(), |
| serviceProviderId.substring(serviceProviderId.indexOf(':') + 1), serviceId)); |
| } |
| }); |
| return object; |
| } |
| |
| /** |
| * Returns the JSON formated list of available services for the service provider |
| * whose String identifier is passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the list of |
| * available services |
| * @param serviceProviderId |
| * the String identifier of the service provider holding the services |
| * |
| * @return the JSON formated list of available services for the specified |
| * service provider |
| */ |
| private String getServices(String identifier, final String serviceProviderId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| final String localNamespace = this.namespace(); |
| String object = remoteCoreInvocation(serviceProviderId, new Executable<SensinactCoreBaseIface, String>() { |
| @Override |
| public String execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| return core.getServices(sessionKey.getPublicKey(), serviceProviderId.substring( |
| serviceProviderId.indexOf(':') + 1)); |
| } |
| }); |
| return object; |
| } |
| |
| /** |
| * Returns the JSON formated description of the service provider whose String |
| * identifier is passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the service |
| * provider description |
| * @param serviceProviderId |
| * the String identifier of the service provider to return the |
| * description of |
| * |
| * @return the JSON formated description of the specified service provider |
| */ |
| private JSONObject getProvider(String identifier, final String serviceProviderId) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| final String localNamespace = this.namespace(); |
| JSONObject object = remoteCoreInvocation(serviceProviderId, new Executable<SensinactCoreBaseIface, JSONObject>() { |
| @Override |
| public JSONObject execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| return new JSONObject(core.getProvider(sessionKey.getPublicKey(), serviceProviderId.substring( |
| serviceProviderId.indexOf(':') + 1))); |
| } |
| }); |
| return object; |
| } |
| |
| /** |
| * Returns the JSON formated list of available service providers for the |
| * {@link Session} whose String identifier is passed as parameter |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} requiring the list of |
| * available service providers |
| * @param filter |
| * @param filterDefinition |
| * |
| * @return the JSON formated list of available service providers |
| */ |
| private String getProviders(String identifier, final String filter) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| String effectiveFilter = null; |
| if (filter != null && filter.length() > 0) { |
| try { |
| mediator.getContext().createFilter(filter); |
| effectiveFilter = filter; |
| |
| } catch (InvalidSyntaxException e) { |
| effectiveFilter = null; |
| } |
| } |
| String local = this.registry.getProviders(sessionKey, sessionKey.localID() != 0, effectiveFilter); |
| |
| if (sessionKey.localID() != 0) { |
| return local; |
| } |
| final StringBuilder content = new StringBuilder(); |
| if (local != null && local.length() > 0) { |
| content.append(local); |
| } |
| final String localNamespace = this.namespace(); |
| AccessController.doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| SensiNact.this.mediator.callServices(SensinactCoreBaseIface.class, null, |
| new Executable<SensinactCoreBaseIface, Void>() { |
| @Override |
| public Void execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| String o = core.getProviders(sessionKey.getPublicKey(), filter); |
| |
| if (o != null && o.length() > 0) { |
| if (content.length() > 0) { |
| content.append(","); |
| } |
| content.append(o); |
| } |
| return null; |
| } |
| }); |
| return null; |
| }}); |
| return content.toString(); |
| } |
| |
| /** |
| * Returns the JSON formated list of all registered resource model instances, |
| * accessible by the {@link Session} whose String identifier is passed as |
| * parameter and compliant to the specified String LDAP formated filter. |
| * |
| * @param identifier |
| * the String identifier of the {@link Session} for which to retrieve |
| * the list of accessible resource model instances |
| * @return the JSON formated list of the resource model instances for the |
| * specified {@link Session} and compliant to the specified filter. |
| */ |
| protected String getAll(String identifier, final String filter) { |
| final SessionKey sessionKey; |
| synchronized(this.sessions){ |
| sessionKey = sessions.get(new KeyExtractor<KeyExtractorType>(KeyExtractorType.TOKEN, identifier)); |
| } |
| String effectiveFilter = null; |
| if (filter != null && filter.length() > 0) { |
| try { |
| mediator.getContext().createFilter(filter); |
| effectiveFilter = filter; |
| |
| } catch (InvalidSyntaxException e) { |
| effectiveFilter = null; |
| } |
| } |
| String local = this.registry.getAll(sessionKey, sessionKey.localID() != 0, effectiveFilter); |
| |
| if (sessionKey.localID() != 0) { |
| return local; |
| } |
| final StringBuilder content = new StringBuilder(); |
| if (local != null && local.length() > 0) { |
| content.append(local); |
| } |
| final String localNamespace = this.namespace(); |
| AccessController.doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| SensiNact.this.mediator.callServices(SensinactCoreBaseIface.class, null, |
| new Executable<SensinactCoreBaseIface, Void>() { |
| @Override |
| public Void execute(SensinactCoreBaseIface core) throws Exception { |
| if(core == null || core.namespace().equals(localNamespace)) { |
| return null; |
| } |
| String o = core.getAll(sessionKey.getPublicKey(), filter); |
| |
| if (o != null && o.length() > 0) { |
| if (content.length() > 0) { |
| content.append(","); |
| } |
| content.append(o); |
| } |
| return null; |
| } |
| }); |
| return null; |
| }}); |
| return content.toString(); |
| } |
| |
| public void close() { |
| mediator.debug("closing sensiNact core"); |
| this.mediator.callService(SensinactCoreBaseIFaceManager.class, |
| new Executable<SensinactCoreBaseIFaceManager,Void>() { |
| @Override |
| public Void execute(SensinactCoreBaseIFaceManager sensinactCoreBaseIFaceManager) throws Exception { |
| sensinactCoreBaseIFaceManager.stop(); |
| return null; |
| } |
| } |
| ); |
| AccessController.<Void>doPrivileged(new PrivilegedAction<Void>() { |
| @Override |
| public Void run() { |
| SensiNact.this.mediator.callServices(SensiNactResourceModel.class, |
| new Executable<SensiNactResourceModel, Void>() { |
| @Override |
| public Void execute(SensiNactResourceModel instance) throws Exception { |
| instance.unregister(); |
| return null; |
| } |
| }); |
| SensiNact.this.mediator.callServices(SnaAgent.class, new Executable<SnaAgent, Void>() { |
| @Override |
| public Void execute(SnaAgent agent) throws Exception { |
| agent.stop(); |
| return null; |
| } |
| }); |
| return null; |
| } |
| }); |
| } |
| |
| String nextToken() { |
| boolean exists = false; |
| String token = null; |
| do { |
| try { |
| token = CryptoUtils.createToken(); |
| } catch (InvalidKeyException e) { |
| token = Long.toHexString(System.currentTimeMillis()); |
| } |
| exists = this.sessions.get(new Sessions.KeyExtractor<Sessions.KeyExtractorType>( |
| Sessions.KeyExtractorType.TOKEN, token)) != null; |
| } while (exists); |
| return token; |
| } |
| } |