Eliminate NormalizedNodePayload.headers
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / rests / 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.nb.rfc8040.rests.services.impl;
9
10 import java.net.URI;
11 import javax.ws.rs.Path;
12 import javax.ws.rs.core.Response;
13 import javax.ws.rs.core.UriInfo;
14 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
15 import org.opendaylight.mdsal.dom.api.DOMNotificationService;
16 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
17 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
18 import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.QueryParams;
19 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
20 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfStreamsSubscriptionService;
21 import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfStreamsConstants;
22 import org.opendaylight.restconf.nb.rfc8040.streams.StreamsConfiguration;
23 import org.opendaylight.yang.gen.v1.subscribe.to.notification.rev161028.Notifi;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
26 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
27 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Implementation of {@link RestconfStreamsSubscriptionService}.
33  */
34 @Path("/")
35 public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSubscriptionService {
36     private static final Logger LOG = LoggerFactory.getLogger(RestconfStreamsSubscriptionServiceImpl.class);
37     private static final QName LOCATION_QNAME = QName.create(Notifi.QNAME, "location").intern();
38     private static final NodeIdentifier LOCATION_NODEID = NodeIdentifier.create(LOCATION_QNAME);
39
40     private final SubscribeToStreamUtil streamUtils;
41     private final HandlersHolder handlersHolder;
42
43     /**
44      * Initialize holder of handlers with holders as parameters.
45      *
46      * @param dataBroker {@link DOMDataBroker}
47      * @param notificationService {@link DOMNotificationService}
48      * @param databindProvider a {@link DatabindProvider}
49      * @param configuration configuration for RESTCONF {@link StreamsConfiguration}}
50      */
51     public RestconfStreamsSubscriptionServiceImpl(final DOMDataBroker dataBroker,
52             final DOMNotificationService notificationService, final DatabindProvider databindProvider,
53             final StreamsConfiguration configuration) {
54         handlersHolder = new HandlersHolder(dataBroker, notificationService, databindProvider);
55         streamUtils = configuration.useSSE() ? SubscribeToStreamUtil.serverSentEvents()
56                 : SubscribeToStreamUtil.webSockets();
57     }
58
59     @Override
60     public Response subscribeToStream(final String identifier, final UriInfo uriInfo) {
61         final var params = QueryParams.newNotificationQueryParams(uriInfo);
62
63         final URI location;
64         if (identifier.contains(RestconfStreamsConstants.DATA_SUBSCRIPTION)) {
65             location = streamUtils.subscribeToDataStream(identifier, uriInfo, params, handlersHolder);
66         } else if (identifier.contains(RestconfStreamsConstants.NOTIFICATION_STREAM)) {
67             location = streamUtils.subscribeToYangStream(identifier, uriInfo, params, handlersHolder);
68         } else {
69             final String msg = "Bad type of notification of sal-remote";
70             LOG.warn(msg);
71             throw new RestconfDocumentedException(msg);
72         }
73
74         return Response.ok()
75             .location(location)
76             .entity(NormalizedNodePayload.of(
77                 Inference.ofDataTreePath(handlersHolder.getDatabindProvider().currentContext().modelContext(),
78                     Notifi.QNAME, LOCATION_QNAME),
79                 ImmutableNodes.leafNode(LOCATION_NODEID, location.toString())))
80             .build();
81     }
82
83     /**
84      * Holder of all handlers for notifications.
85      */
86     // FIXME: why do we even need this class?!
87     public static final class HandlersHolder {
88         private final DOMDataBroker dataBroker;
89         private final DOMNotificationService notificationService;
90         private final DatabindProvider databindProvider;
91
92         private HandlersHolder(final DOMDataBroker dataBroker, final DOMNotificationService notificationService,
93                 final DatabindProvider databindProvider) {
94             this.dataBroker = dataBroker;
95             this.notificationService = notificationService;
96             this.databindProvider = databindProvider;
97         }
98
99         /**
100          * Get {@link DOMDataBroker}.
101          *
102          * @return the dataBroker
103          */
104         public DOMDataBroker getDataBroker() {
105             return dataBroker;
106         }
107
108         /**
109          * Get {@link DOMNotificationService}.
110          *
111          * @return the notificationService
112          */
113         public DOMNotificationService getNotificationServiceHandler() {
114             return notificationService;
115         }
116
117         /**
118          * Get {@link DatabindProvider}.
119          *
120          * @return the schemaHandler
121          */
122         public DatabindProvider getDatabindProvider() {
123             return databindProvider;
124         }
125     }
126 }