Implement simple-ird
[alto.git] / alto-basic / simple-ird / impl / src / main / java / org / opendaylight / alto / basic / impl / SimpleIrdRoute.java
1 /*
2  * Copyright (c) 2015 Yale University and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.alto.basic.impl;
10
11 import java.util.HashMap;
12 import java.util.LinkedList;
13 import java.util.List;
14 import java.util.Map;
15
16 import javax.servlet.http.HttpServletRequest;
17
18 import javax.ws.rs.GET;
19 import javax.ws.rs.Path;
20 import javax.ws.rs.PathParam;
21 import javax.ws.rs.Produces;
22 import javax.ws.rs.core.Context;
23 import javax.ws.rs.core.Response;
24
25 import org.opendaylight.alto.core.northbound.api.AltoNorthboundRoute;
26
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rev151021.IrdInstance;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rev151021.ird.entry.configuration.data.location.FixedUrl;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rev151021.ird.entry.configuration.data.location.RelativePath;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rev151021.ird.entry.data.EntryCapabilities;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rev151021.ird.instance.IrdEntry;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rfc7285.rev151021.Rfc7285CostTypeCapabilities;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rfc7285.rev151021.Rfc7285IrdMeta;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rfc7285.rev151021.Rfc7285IrdMetadata;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.basic.simple.ird.rfc7285.rev151021.rfc7285.ird.meta.CostType;
36
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.types.rev150921.ResourceId;
38
39 @Path("/")
40 public class SimpleIrdRoute implements AltoNorthboundRoute {
41
42     public static final String ALTO_IRD = "application/alto-directory+json";
43
44     private AltoSimpleIrdProvider m_provider = null;
45
46     public SimpleIrdRoute(AltoSimpleIrdProvider provider) {
47         m_provider = provider;
48     }
49
50     @Path("{path:.+}")
51     @GET
52     @Produces({ALTO_IRD, ALTO_ERROR})
53     public Response route(@Context HttpServletRequest req, @PathParam("path") String path) {
54         if (m_provider == null) {
55             return Response.status(Response.Status.NOT_FOUND).build();
56         }
57
58         IrdInstance ird = m_provider.getInstance(new ResourceId(path));
59         if (ird == null) {
60             return Response.status(Response.Status.NOT_FOUND).build();
61         }
62
63         try {
64             Rfc7285Ird rfcIrd = convert(ird, req);
65             return Response.ok(rfcIrd, ALTO_IRD).build();
66         } catch (Exception e) {
67             e.printStackTrace();
68         }
69
70         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
71     }
72
73     private static class Rfc7285Ird {
74
75         public Map<String, Object> meta = new HashMap<String, Object>();
76
77         public Map<String, Object> resources = new HashMap<String, Object>();
78     }
79
80     private Rfc7285Ird convert(IrdInstance ird, HttpServletRequest req) {
81         Rfc7285Ird rfcIrd = new Rfc7285Ird();
82
83         Rfc7285IrdMetadata metadata = ird.getAugmentation(Rfc7285IrdMetadata.class);
84         if (metadata != null) {
85             Rfc7285IrdMeta meta = metadata.getMeta();
86
87             if (meta != null) {
88                 if (meta.getDefaultNetworkMap() != null) {
89                     rfcIrd.meta.put("default-alto-network-map", meta.getDefaultNetworkMap().getValue());
90                 }
91
92                 if (meta.getCostType() != null) {
93                     Map<String, Object> costTypes = new HashMap<String, Object>();
94                     for (CostType type: meta.getCostType()) {
95                         Map<String, Object> costType = new HashMap<String, Object>();
96                         costType.put("cost-mode", type.getCostMode());
97                         costType.put("cost-metric", type.getCostMetric().getValue());
98
99                         //TODO Support 'description' field
100
101                         costTypes.put(type.getName(), costType);
102                     }
103
104                     rfcIrd.meta.put("cost-types", costTypes);
105                 }
106             }
107         }
108
109         List<IrdEntry> resourceList = ird.getIrdEntry();
110         if (resourceList == null)
111             return rfcIrd;
112
113         for (IrdEntry entry: resourceList) {
114             Map<String, Object> resource = new HashMap<String, Object>();
115
116             if (entry.getLocation() instanceof FixedUrl) {
117                 FixedUrl url = (FixedUrl)entry.getLocation();
118                 resource.put("uri", url.getUri().getValue());
119             } else if (entry.getLocation() instanceof RelativePath) {
120                 RelativePath relativePath = (RelativePath)entry.getLocation();
121                 String path = relativePath.getPath().getValue();
122
123                 String uri = req.getScheme() + "://" + req.getLocalName()
124                                 + ":" + req.getLocalPort() + path;
125
126                 resource.put("uri", uri);
127             }
128
129             if (entry.getAccepts() != null) {
130                 resource.put("accepts", entry.getAccepts());
131             }
132
133             if (entry.getMediaType() != null) {
134                 resource.put("media-type", entry.getMediaType());
135             }
136
137             if (entry.getEntryCapabilities() != null) {
138                 EntryCapabilities capabilities = entry.getEntryCapabilities();
139                 Map<String, Object> capabilityMap = new HashMap<String, Object>();
140
141                 Rfc7285CostTypeCapabilities costTypeCapabilities;
142                 costTypeCapabilities = capabilities.getAugmentation(Rfc7285CostTypeCapabilities.class);
143                 if (costTypeCapabilities != null) {
144                     capabilityMap.put("cost-type-names", costTypeCapabilities.getCostTypeNames());
145                     capabilityMap.put("cost-constraints", costTypeCapabilities.isCostConstraints());
146                 }
147
148                 if (!capabilityMap.isEmpty()) {
149                     resource.put("capabilities", capabilityMap);
150                 }
151             }
152
153             if ((entry.getUses() != null) && (!entry.getUses().isEmpty())) {
154                 List<String> uses = new LinkedList<>();
155                 for (ResourceId rid: entry.getUses()) {
156                     uses.add(rid.getValue());
157                 }
158                 resource.put("uses", uses);
159             }
160
161             rfcIrd.resources.put(entry.getEntryId().getValue(), resource);
162         }
163         return rfcIrd;
164     }
165 }