6b0cbe3c2b178e8baaabdf2664f1a48de67ad449
[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         Date start = null;
60         Date stop = null;
61
62         for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
63             switch (entry.getKey()) {
64                 case "start-time":
65                     if (!startTime_used) {
66                         startTime_used = true;
67                         start = SubscribeToStreamUtil.parseDateFromQueryParam(entry);
68                     } else {
69                         throw new RestconfDocumentedException("Start-time parameter can be used only once.");
70                     }
71                     break;
72                 case "stop-time":
73                     if (!stopTime_used) {
74                         stopTime_used = true;
75                         stop = SubscribeToStreamUtil.parseDateFromQueryParam(entry);
76                     } else {
77                         throw new RestconfDocumentedException("Stop-time parameter can be used only once.");
78                     }
79                     break;
80                 default:
81                     throw new RestconfDocumentedException("Bad parameter used with notifications: " + entry.getKey());
82             }
83         }
84         if (!startTime_used && stopTime_used) {
85             throw new RestconfDocumentedException("Stop-time parameter has to be used with start-time parameter.");
86         }
87         URI response = null;
88         if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCR)) {
89             response = SubscribeToStreamUtil.dataSubs(identifier, uriInfo, start, stop, this.domDataBrokerHandler);
90         } else if (identifier.contains(RestconfStreamsConstants.NOTIFICATION_STREAM)) {
91             response = SubscribeToStreamUtil.notifStream(identifier, uriInfo, start, stop,
92                     this.notificationServiceHandler);
93         }
94
95         if (response != null) {
96             // prepare node with value of location
97             final InstanceIdentifierContext<?> iid =
98                     SubscribeToStreamUtil.prepareIIDSubsStreamOutput(this.schemaHandler);
99             final NormalizedNodeAttrBuilder<NodeIdentifier, Object, LeafNode<Object>> builder =
100                     ImmutableLeafNodeBuilder.create().withValue(response.toString());
101             builder.withNodeIdentifier(
102                     NodeIdentifier.create(QName.create("subscribe:to:notification", "2016-10-28", "location")));
103
104             // prepare new header with location
105             final Map<String, Object> headers = new HashMap<>();
106             headers.put("Location", response);
107
108             return new NormalizedNodeContext(iid, builder.build(), headers);
109         }
110
111         final String msg = "Bad type of notification of sal-remote";
112         LOG.warn(msg);
113         throw new RestconfDocumentedException(msg);
114     }
115 }