9852330a0e532a0e84e5989d43c296db0d405df5
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / restconf / restful / services / impl / RestconfStreamsSubscriptionServiceImpl.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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 package org.opendaylight.restconf.restful.services.impl;
9
10 import java.net.URI;
11 import java.util.Date;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import javax.ws.rs.core.UriInfo;
17 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
18 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
19 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
20 import org.opendaylight.restconf.handlers.DOMDataBrokerHandler;
21 import org.opendaylight.restconf.handlers.NotificationServiceHandler;
22 import org.opendaylight.restconf.handlers.SchemaContextHandler;
23 import org.opendaylight.restconf.restful.services.api.RestconfStreamsSubscriptionService;
24 import org.opendaylight.restconf.restful.utils.RestconfStreamsConstants;
25 import org.opendaylight.restconf.restful.utils.SubscribeToStreamUtil;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
29 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
30 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * Implementation of {@link RestconfStreamsSubscriptionService}
36  *
37  */
38 public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSubscriptionService {
39
40     private static final Logger LOG = LoggerFactory.getLogger(RestconfStreamsSubscriptionServiceImpl.class);
41
42     private final DOMDataBrokerHandler domDataBrokerHandler;
43
44     private final NotificationServiceHandler notificationServiceHandler;
45
46     private final SchemaContextHandler schemaHandler;
47
48     public RestconfStreamsSubscriptionServiceImpl(final DOMDataBrokerHandler domDataBrokerHandler,
49             final NotificationServiceHandler notificationServiceHandler, final SchemaContextHandler schemaHandler) {
50         this.domDataBrokerHandler = domDataBrokerHandler;
51         this.notificationServiceHandler = notificationServiceHandler;
52         this.schemaHandler = schemaHandler;
53     }
54
55     @Override
56     public NormalizedNodeContext subscribeToStream(final String identifier, final UriInfo uriInfo) {
57         boolean startTime_used = false;
58         boolean stopTime_used = false;
59         boolean filter_used = false;
60         Date start = null;
61         Date stop = null;
62         String filter = null;
63
64         for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
65             switch (entry.getKey()) {
66                 case "start-time":
67                     if (!startTime_used) {
68                         startTime_used = true;
69                         start = SubscribeToStreamUtil.parseDateFromQueryParam(entry);
70                     } else {
71                         throw new RestconfDocumentedException("Start-time parameter can be used only once.");
72                     }
73                     break;
74                 case "stop-time":
75                     if (!stopTime_used) {
76                         stopTime_used = true;
77                         stop = SubscribeToStreamUtil.parseDateFromQueryParam(entry);
78                     } else {
79                         throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
80                     }
81                     break;
82                 case "filter":
83                     if (!filter_used) {
84                         filter_used = true;
85                         filter = entry.getValue().iterator().next();
86                     }
87                     break;
88                 default:
89                     throw new RestconfDocumentedException("Bad parameter used with notifications: " + entry.getKey());
90             }
91         }
92         if (!startTime_used && stopTime_used) {
93             throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
94         }
95         URI response = null;
96         if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCR)) {
97             response =
98                     SubscribeToStreamUtil.dataSubs(identifier, uriInfo, start, stop, this.domDataBrokerHandler, filter);
99         } else if (identifier.contains(RestconfStreamsConstants.NOTIFICATION_STREAM)) {
100             response = SubscribeToStreamUtil.notifStream(identifier, uriInfo, start, stop,
101                     this.notificationServiceHandler, filter);
102         }
103
104         if (response != null) {
105             // prepare node with value of location
106             final InstanceIdentifierContext<?> iid =
107                     SubscribeToStreamUtil.prepareIIDSubsStreamOutput(this.schemaHandler);
108             final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> builder =
109                     ImmutableLeafNodeBuilder.create().withValue(response.toString());
110             builder.withNodeIdentifier(
111                     NodeIdentifier.create(QName.create("subscribe:to:notification", "2016-10-28", "location")));
112
113             // prepare new header with location
114             final Map<String, Object> headers = new HashMap<>();
115             headers.put("Location", response);
116
117             return new NormalizedNodeContext(iid, builder.build(), headers);
118         }
119
120         final String msg = "Bad type of notification of sal-remote";
121         LOG.warn(msg);
122         throw new RestconfDocumentedException(msg);
123     }
124 }