| package org.eclipse.sensinact.gateway.core; |
| |
| import org.eclipse.sensinact.gateway.common.bundle.Mediator; |
| import org.eclipse.sensinact.gateway.common.execution.Executable; |
| import org.eclipse.sensinact.gateway.core.method.AccessMethod; |
| import org.eclipse.sensinact.gateway.core.remote.SensinactCoreBaseIFaceManager; |
| import org.eclipse.sensinact.gateway.core.security.AccessLevelOption; |
| import org.eclipse.sensinact.gateway.core.security.AccessNode; |
| import org.eclipse.sensinact.gateway.core.security.AccessTree; |
| import org.eclipse.sensinact.gateway.util.UriUtils; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceReference; |
| |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.util.*; |
| |
| @SuppressWarnings({"rawtypes","unchecked"}) |
| public final class RegistryEndpoint { |
| |
| private Mediator mediator; |
| private final String defaultLocation; |
| |
| public RegistryEndpoint(Mediator mediator){ |
| this.mediator = mediator; |
| this.defaultLocation = ModelInstance.defaultLocation(mediator); |
| } |
| |
| protected Collection<ServiceReference<SensiNactResourceModel>> getReferences(SessionKey sessionKey, String filter) { |
| return getReferences(sessionKey.getAccessTree(),filter); |
| } |
| |
| protected Collection<ServiceReference<SensiNactResourceModel>> getReferences(AccessTree<? extends AccessNode> tree, String filter) { |
| AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE); |
| Collection<ServiceReference<SensiNactResourceModel>> result = new ArrayList<ServiceReference<SensiNactResourceModel>>(); |
| Collection<ServiceReference<SensiNactResourceModel>> references = null; |
| try { |
| references = mediator.getContext().getServiceReferences(SensiNactResourceModel.class, filter); |
| Iterator<ServiceReference<SensiNactResourceModel>> iterator = references.iterator(); |
| |
| while (iterator.hasNext()) { |
| ServiceReference<SensiNactResourceModel> reference = iterator.next(); |
| String name = (String) reference.getProperty("name"); |
| Integer level = (Integer) reference.getProperty(name.concat(".DESCRIBE")); |
| if (level == null) { |
| level = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel()); |
| } |
| AccessNode node = tree.getRoot().get(UriUtils.getUri(new String[] { name })); |
| if (node == null) { |
| node = tree.getRoot(); |
| } |
| if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() >= level.intValue()) { |
| result.add(reference); |
| } |
| } |
| } catch (InvalidSyntaxException e) { |
| mediator.error(e.getMessage(), e); |
| } |
| return result; |
| } |
| |
| public Set<ServiceProvider> serviceProviders(final SessionKey sessionKey, String filter) { |
| String activeFilter = "(lifecycle.status=ACTIVE)"; |
| String providersFilter = null; |
| |
| if (filter == null) { |
| providersFilter = activeFilter; |
| |
| } else { |
| StringBuilder filterBuilder = new StringBuilder().append("(&"); |
| if (!filter.startsWith("(")) { |
| filterBuilder.append("("); |
| } |
| filterBuilder.append(filter); |
| if (!filter.endsWith(")")) { |
| filterBuilder.append(")"); |
| } |
| filterBuilder.append(activeFilter); |
| filterBuilder.append(")"); |
| providersFilter = filterBuilder.toString(); |
| } |
| final String fltr = providersFilter; |
| |
| Set<ServiceProvider> serviceProviders = AccessController.<Set<ServiceProvider>>doPrivileged( |
| new PrivilegedAction<Set<ServiceProvider>>() { |
| @Override |
| public Set<ServiceProvider> run() { |
| Collection<ServiceReference<SensiNactResourceModel>> references = |
| RegistryEndpoint.this.getReferences(sessionKey, fltr); |
| |
| Iterator<ServiceReference<SensiNactResourceModel>> iterator = |
| references.iterator(); |
| |
| Set<ServiceProvider> providers = new HashSet<ServiceProvider>(); |
| |
| while (iterator.hasNext()) { |
| ServiceReference<SensiNactResourceModel> ref = iterator.next(); |
| SensiNactResourceModel model = mediator.getContext().getService(ref); |
| ServiceProvider provider = null; |
| try { |
| provider = (ServiceProvider) model.getRootElement().getProxy( |
| sessionKey.getAccessTree()); |
| |
| } catch (ModelElementProxyBuildException e) { |
| mediator.error(e); |
| } |
| if (provider != null && provider.isAccessible()) |
| providers.add(provider); |
| } |
| return providers; |
| } |
| }); |
| return serviceProviders; |
| } |
| |
| public ServiceProvider serviceProvider(SessionKey sessionKey, final String serviceProviderName) { |
| ServiceProvider provider = null; |
| |
| Set<ServiceProvider> providers = this.serviceProviders(sessionKey, |
| new StringBuilder().append("(name=").append(serviceProviderName).append(")").toString()); |
| |
| if (providers == null || providers.size() != 1) { |
| return provider; |
| } |
| provider = providers.iterator().next(); |
| return provider; |
| } |
| |
| public Service service(SessionKey sessionKey, String serviceProviderName, String serviceName) { |
| ServiceProvider serviceProvider = serviceProvider(sessionKey, serviceProviderName); |
| Service service = null; |
| if (serviceProvider != null) { |
| service = serviceProvider.getService(serviceName); |
| } |
| return service; |
| } |
| |
| public Resource resource(SessionKey sessionKey, String serviceProviderName, String serviceName, |
| String resourceName) { |
| Service service = this.service(sessionKey, serviceProviderName, serviceName); |
| Resource resource = null; |
| if (service != null) |
| resource = service.getResource(resourceName); |
| return resource; |
| } |
| |
| public boolean isAccessible(AccessTree<? extends AccessNode> tree, String path) { |
| String[] uriElements = UriUtils.getUriElements(path); |
| String providerName = uriElements[0]; |
| String serviceName = uriElements.length>1?uriElements[1]:null; |
| String resourceName = uriElements.length>2?uriElements[2]:null; |
| |
| String filter = new StringBuilder().append("(&(name=").append(providerName |
| ).append(")(lifecycle.status=ACTIVE))").toString(); |
| |
| Collection<ServiceReference<SensiNactResourceModel>> references = |
| this.getReferences(tree, filter); |
| if(references.size()!=1) { |
| return false; |
| } |
| ServiceReference<SensiNactResourceModel> reference = references.iterator().next(); |
| |
| AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE); |
| AccessNode node = tree.getRoot(); |
| |
| int index = 0; |
| String pa = null; |
| String key = null; |
| |
| Integer inheritedObjectDescribeLevel = Integer.valueOf( |
| AccessLevelOption.OWNER.getAccessLevel().getLevel()); |
| |
| while(true) { |
| switch(index) { |
| case 0: |
| pa = UriUtils.getUri(new String[] {providerName}); |
| key = providerName.concat(".DESCRIBE"); |
| break; |
| case 1: |
| List<String> services = (List<String>) reference.getProperty("services"); |
| if(services == null || !services.contains(serviceName)) { |
| return false; |
| } |
| pa = UriUtils.getUri(new String[] {pa,serviceName}); |
| key = new StringBuilder().append(serviceName).append(".DESCRIBE").toString(); |
| break; |
| case 2: |
| List<String> resources = (List<String>) reference.getProperty(serviceName.concat(".resources")); |
| if(resources == null || !resources.contains(resourceName)) { |
| return false; |
| } |
| pa = UriUtils.getUri(new String[] {pa,resourceName}); |
| key = new StringBuilder().append(serviceName).append(".").append(resourceName).append(".DESCRIBE").toString(); |
| break; |
| default: |
| return false; |
| } |
| AccessNode tmpNode = tree.getRoot().get(pa); |
| if (tmpNode == null) { |
| tmpNode = node; |
| } else{ |
| node = tmpNode; |
| } |
| Integer level = (Integer) reference.getProperty(key); |
| if(level == null) { |
| level = inheritedObjectDescribeLevel; |
| }else { |
| inheritedObjectDescribeLevel = level; |
| } |
| if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < inheritedObjectDescribeLevel.intValue()) { |
| return false; |
| } |
| if(++index == uriElements.length) { |
| return true; |
| } |
| } |
| } |
| |
| public String getAll(SessionKey sessionKey, boolean resolveNamespace, String filter) { |
| StringBuilder builder = new StringBuilder(); |
| int index = -1; |
| |
| Collection<ServiceReference<SensiNactResourceModel>> references = |
| RegistryEndpoint.this.getReferences(sessionKey, filter); |
| Iterator<ServiceReference<SensiNactResourceModel>> iterator = |
| references.iterator(); |
| |
| AccessTree<? extends AccessNode> tree = sessionKey.getAccessTree(); |
| AccessMethod.Type describe = AccessMethod.Type.valueOf(AccessMethod.DESCRIBE); |
| |
| String namespace = namespace(); |
| String prefix = ""; |
| |
| while (iterator.hasNext()) { |
| index++; |
| ServiceReference<SensiNactResourceModel> reference = iterator.next(); |
| String name = (String) reference.getProperty("name"); |
| |
| String provider = new StringBuilder().append(prefix).append(name).toString(); |
| |
| String location = null; |
| Object obj = reference.getProperty(ModelInstanceRegistration.LOCATION_PROPERTY.concat(".value")); |
| if (obj != null) { |
| location = String.valueOf(obj).replace('"', '\''); |
| } |
| location = (location == null || location.length() == 0) ? defaultLocation : location; |
| List<String> serviceList = (List<String>) reference.getProperty("services"); |
| |
| builder.append(index > 0 ? ',' : ""); |
| builder.append('{'); |
| builder.append("\"name\":"); |
| builder.append('"'); |
| if(!SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE.equals(namespace) && sessionKey.localID()!=0) { |
| builder.append(namespace); |
| builder.append(":"); |
| } |
| builder.append(provider); |
| builder.append('"'); |
| if(!SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE.equals(namespace)) { |
| builder.append(",\"namespace\":"); |
| builder.append('"'); |
| builder.append(namespace); |
| builder.append('"'); |
| } |
| builder.append(",\"location\":"); |
| builder.append('"'); |
| builder.append(location); |
| builder.append('"'); |
| builder.append(",\"services\":"); |
| builder.append('['); |
| |
| int sindex = 0; |
| int slength = serviceList == null ? 0 : serviceList.size(); |
| for (; sindex < slength; sindex++) { |
| String service = serviceList.get(sindex); |
| String serviceUri = UriUtils.getUri(new String[] { name, service }); |
| Integer serviceLevel = (Integer) reference.getProperty(service.concat(".DESCRIBE")); |
| if (serviceLevel == null) { |
| serviceLevel = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel()); |
| } |
| AccessNode node = sessionKey.getAccessTree().getRoot().get(serviceUri); |
| if (node == null) { |
| node = tree.getRoot(); |
| } |
| int describeAccessLevel = node.getAccessLevelOption(describe).getAccessLevel().getLevel(); |
| int serviceLevelLevel = serviceLevel.intValue(); |
| |
| if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < serviceLevel.intValue()) { |
| continue; |
| } |
| List<String> resourceList = (List<String>) reference.getProperty(service.concat(".resources")); |
| |
| builder.append(sindex > 0 ? ',' : ""); |
| builder.append('{'); |
| builder.append("\"name\":"); |
| builder.append('"'); |
| builder.append(service); |
| builder.append('"'); |
| builder.append(",\"resources\":"); |
| builder.append('['); |
| |
| int rindex = 0; |
| int rlength = resourceList == null ? 0 : resourceList.size(); |
| for (; rindex < rlength; rindex++) { |
| String resource = resourceList.get(rindex); |
| String resolvedResource = new StringBuilder().append(service).append(".").append(resource).toString(); |
| String resourceUri = UriUtils.getUri(new String[] { name, service, resource }); |
| Integer resourceLevel = (Integer) reference.getProperty(resolvedResource.concat(".DESCRIBE")); |
| |
| if (resourceLevel == null) |
| resourceLevel = Integer.valueOf(AccessLevelOption.OWNER.getAccessLevel().getLevel()); |
| |
| node = sessionKey.getAccessTree().getRoot().get(resourceUri); |
| if (node == null) |
| node = tree.getRoot(); |
| |
| if (node.getAccessLevelOption(describe).getAccessLevel().getLevel() < resourceLevel.intValue()) |
| continue; |
| |
| String type = (String) reference.getProperty(resolvedResource.concat(".type")); |
| String rws = null; |
| |
| switch(type) { |
| case "PROPERTY": |
| case "STATE_VARIABLE": |
| case "SENSOR": |
| StringBuilder sbuilder = new StringBuilder(); |
| sbuilder.append(resolvedResource); |
| sbuilder.append("."); |
| sbuilder.append(DataResource.VALUE); |
| sbuilder.append("."); |
| sbuilder.append(Metadata.MODIFIABLE); |
| String st = (String) reference.getProperty(sbuilder.toString()); |
| if(st!=null) { |
| switch(st) { |
| case "MODIFIABLE": |
| rws = "RW"; |
| break; |
| case "FIXED": |
| case "UPDATABLE": |
| rws = "RO"; |
| break; |
| default: |
| break; |
| } |
| } |
| break; |
| case "ACTION": |
| default: |
| break; |
| } |
| builder.append(rindex > 0 ? ',' : ""); |
| builder.append('{'); |
| builder.append("\"name\":"); |
| builder.append('"'); |
| builder.append(resource); |
| builder.append('"'); |
| builder.append(",\"type\":"); |
| builder.append('"'); |
| builder.append(type); |
| builder.append('"'); |
| if(rws != null) { |
| builder.append(",\"rws\":"); |
| builder.append('"'); |
| builder.append(rws); |
| builder.append('"'); |
| } |
| builder.append('}'); |
| } |
| builder.append(']'); |
| builder.append('}'); |
| } |
| builder.append(']'); |
| builder.append('}'); |
| } |
| String content = builder.toString(); |
| return content; |
| } |
| |
| public String getProviders(SessionKey sessionKey, boolean resolveNamespace, String filter) { |
| try{ |
| String prefix = resolveNamespace |
| ? new StringBuilder().append(namespace()).append(":").toString() |
| : ""; |
| Collection<ServiceReference<SensiNactResourceModel>> references = this.getReferences(sessionKey, filter); |
| Iterator<ServiceReference<SensiNactResourceModel>> iterator = references.iterator(); |
| |
| StringBuilder builder = new StringBuilder(); |
| int index = 0; |
| while (iterator.hasNext()) { |
| ServiceReference<SensiNactResourceModel> reference = iterator.next(); |
| String name = (String) reference.getProperty("name"); |
| String provider = new StringBuilder().append(prefix).append(name).toString(); |
| if (index > 0) { |
| builder.append(","); |
| } |
| builder.append('"'); |
| builder.append(provider); |
| builder.append('"'); |
| index++; |
| } |
| String content = builder.toString(); |
| return content; |
| }catch(Exception e){ |
| e.printStackTrace(); |
| return ""; |
| } |
| } |
| |
| protected String namespace() { |
| String namespace = this.mediator.callService(SensinactCoreBaseIFaceManager.class, |
| new Executable<SensinactCoreBaseIFaceManager,String>() { |
| @Override |
| public String execute(SensinactCoreBaseIFaceManager sensinactCoreBaseIFaceManager) throws Exception { |
| return sensinactCoreBaseIFaceManager.namespace(); |
| } |
| } |
| ); |
| return namespace==null?SensinactCoreBaseIFaceManager.EMPTY_NAMESPACE:namespace; |
| } |
| }; |