X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-docgen%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frest%2Fdoc%2Fmountpoints%2FMountPointSwagger.java;fp=opendaylight%2Fmd-sal%2Fsal-rest-docgen%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frest%2Fdoc%2Fmountpoints%2FMountPointSwagger.java;h=b996bf12348ccc89088b1426c269049a9cf98928;hp=0000000000000000000000000000000000000000;hb=237c0e41ac33d7b3367b8e1a038bfba4c6431610;hpb=f6609a5ab258b69a0d8ae2a97ee140b4da3b82ba diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java new file mode 100644 index 0000000000..b996bf1234 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. 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 + */ +package org.opendaylight.controller.sal.rest.doc.mountpoints; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +import javax.ws.rs.core.UriInfo; + +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener; +import org.opendaylight.controller.sal.rest.doc.impl.BaseYangSwaggerGenerator; +import org.opendaylight.controller.sal.rest.doc.swagger.Api; +import org.opendaylight.controller.sal.rest.doc.swagger.ApiDeclaration; +import org.opendaylight.controller.sal.rest.doc.swagger.Operation; +import org.opendaylight.controller.sal.rest.doc.swagger.Resource; +import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +public class MountPointSwagger extends BaseYangSwaggerGenerator implements MountProvisionListener { + + private static final String DATASTORES_REVISION = "-"; + private static final String DATASTORES_LABEL = "Datastores"; + + private MountProvisionService mountService; + private final Map instanceIdToLongId = new TreeMap<>( + new Comparator() { + @Override + public int compare(InstanceIdentifier o1, InstanceIdentifier o2) { + return o1.toString().compareToIgnoreCase(o2.toString()); + } + }); + private final Map longIdToInstanceId = new HashMap<>(); + private final Object lock = new Object(); + + private final AtomicLong idKey = new AtomicLong(0); + + private static AtomicReference selfRef = new AtomicReference<>(); + private SchemaService globalSchema; + + public Map getInstanceIdentifiers() { + Map urlToId = new HashMap<>(); + synchronized (lock) { + SchemaContext context = globalSchema.getGlobalContext(); + for (Entry entry : instanceIdToLongId.entrySet()) { + String modName = findModuleName(entry.getKey(), context); + urlToId.put(generateUrlPrefixFromInstanceID(entry.getKey(), modName), + entry.getValue()); + } + } + return urlToId; + } + + public void setGlobalSchema(SchemaService globalSchema) { + this.globalSchema = globalSchema; + } + + private String findModuleName(InstanceIdentifier id, SchemaContext context) { + PathArgument rootQName = id.getPath().get(0); + for (Module mod : context.getModules()) { + if (mod.getDataChildByName(rootQName.getNodeType()) != null) { + return mod.getName(); + } + } + return null; + } + + private String generateUrlPrefixFromInstanceID(InstanceIdentifier key, String moduleName) { + List path = key.getPath(); + StringBuilder builder = new StringBuilder(); + if (moduleName != null) { + builder.append(moduleName); + builder.append(":"); + } + boolean first = true; + for (PathArgument arg : path) { + + String name = arg.getNodeType().getLocalName(); + if (first) { + first = false; + } else { + builder.append("/"); + } + builder.append(name); + if (arg instanceof InstanceIdentifier.NodeIdentifierWithPredicates) { + NodeIdentifierWithPredicates nodeId = (NodeIdentifierWithPredicates) arg; + for (Entry entry : nodeId.getKeyValues().entrySet()) { + builder.append("/").append(entry.getValue()); + } + } + } + + return builder.append("/").toString(); + } + + private String getYangMountUrl(InstanceIdentifier key) { + String modName = findModuleName(key, globalSchema.getGlobalContext()); + return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount/"; + } + + public ResourceList getResourceList(UriInfo uriInfo, Long id) { + InstanceIdentifier iid = getInstanceId(id); + if (iid == null) { + return null; // indicating not found. + } + SchemaContext context = getSchemaContext(iid); + String urlPrefix = getYangMountUrl(iid); + if (context == null) { + return createResourceList(); + } + List resources = new LinkedList<>(); + Resource dataStores = new Resource(); + dataStores.setDescription("Provides methods for accessing the data stores."); + dataStores.setPath(generatePath(uriInfo, DATASTORES_LABEL, DATASTORES_REVISION)); + resources.add(dataStores); + ResourceList list = super.getResourceListing(uriInfo, context, urlPrefix); + resources.addAll(list.getApis()); + list.setApis(resources); + return list; + } + + private InstanceIdentifier getInstanceId(Long id) { + InstanceIdentifier instanceId; + synchronized (lock) { + instanceId = longIdToInstanceId.get(id); + } + return instanceId; + } + + private SchemaContext getSchemaContext(InstanceIdentifier id) { + + if (id == null) { + return null; + } + + MountProvisionInstance mountPoint = mountService.getMountPoint(id); + if (mountPoint == null) { + return null; + } + + SchemaContext context = mountPoint.getSchemaContext(); + if (context == null) { + return null; + } + return context; + } + + public ApiDeclaration getMountPointApi(UriInfo uriInfo, Long id, String module, String revision) { + InstanceIdentifier iid = getInstanceId(id); + SchemaContext context = getSchemaContext(iid); + String urlPrefix = getYangMountUrl(iid); + if (context == null) { + return null; + } + + if (DATASTORES_LABEL.equals(module) && DATASTORES_REVISION.equals(revision)) { + return generateDataStoreApiDoc(uriInfo, urlPrefix); + } + return super.getApiDeclaration(module, revision, uriInfo, context, urlPrefix); + } + + private ApiDeclaration generateDataStoreApiDoc(UriInfo uriInfo, String context) { + + ApiDeclaration declaration = super.createApiDeclaration(createBasePathFromUriInfo(uriInfo)); + List apis = new LinkedList<>(); + apis.add(createGetApi("config", + "Queries the config (startup) datastore on the mounted hosted.", context)); + apis.add(createGetApi("operational", + "Queries the operational (running) datastore on the mounted hosted.", context)); + apis.add(createGetApi("operations", + "Queries the available operations (RPC calls) on the mounted hosted.", context)); + declaration.setApis(apis); + return declaration; + + } + + private Api createGetApi(String datastore, String note, String context) { + Operation getConfig = new Operation(); + getConfig.setMethod("GET"); + getConfig.setNickname("GET " + datastore); + getConfig.setNotes(note); + + Api api = new Api(); + api.setPath(getDataStorePath("/" + datastore + "/", context)); + api.setOperations(Collections.singletonList(getConfig)); + + return api; + } + + public void setMountService(MountProvisionService mountService) { + this.mountService = mountService; + } + + @Override + public void onMountPointCreated(InstanceIdentifier path) { + synchronized (lock) { + Long idLong = idKey.incrementAndGet(); + instanceIdToLongId.put(path, idLong); + longIdToInstanceId.put(idLong, path); + } + } + + @Override + public void onMountPointRemoved(InstanceIdentifier path) { + synchronized (lock) { + Long id = instanceIdToLongId.remove(path); + longIdToInstanceId.remove(id); + } + } + + public static MountPointSwagger getInstance() { + MountPointSwagger swagger = selfRef.get(); + if (swagger == null) { + selfRef.compareAndSet(null, new MountPointSwagger()); + swagger = selfRef.get(); + } + return swagger; + } + +}