29e3347f68fec6cb5f1106963304b581b62cf5c6
[dcaegen2/services/sdk.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * DCAEGEN2-SERVICES-SDK
4  * ================================================================================
5  * Copyright (C) 2019 Nokia. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.dcaegen2.services.sdk.services.hvves.client.producer.impl.encoders;
22
23 import io.netty.buffer.ByteBuf;
24 import io.netty.buffer.ByteBufAllocator;
25 import io.vavr.control.Try;
26 import org.onap.dcaegen2.services.sdk.services.hvves.client.producer.api.options.WireFrameVersion;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.nio.ByteBuffer;
31
32 /**
33  * @author <a href="mailto:jakub.dudycz@nokia.com">Jakub Dudycz</a>
34  */
35 public class WireFrameEncoder {
36     private static final Logger LOGGER = LoggerFactory.getLogger(WireFrameEncoder.class);
37     private static final short MARKER_BYTE = 0xAA;
38     private static final int RESERVED_BYTES_COUNT = 3;
39     private static final int HEADER_SIZE = 1 * Byte.BYTES +         // marker
40             2 * Byte.BYTES +                                        // single byte fields (versions)
41             RESERVED_BYTES_COUNT * Byte.BYTES +                     // reserved bytes
42             1 * Short.BYTES +                                       // paylaod type
43             1 * Integer.BYTES;                                      // payload length
44
45     private final ByteBufAllocator allocator;
46     private final WireFrameVersion wireFrameVersion;
47
48     public WireFrameEncoder(ByteBufAllocator allocator, WireFrameVersion wireFrameVersion) {
49         this.allocator = allocator;
50         this.wireFrameVersion = wireFrameVersion;
51     }
52
53     public Try<ByteBuf> encode(ByteBuffer payload) {
54         return Try.of(() -> encodeMessageAs(payload, PayloadType.PROTOBUF))
55                 .onFailure((ex) -> LOGGER.warn("Failed to encode payload", ex));
56     }
57
58     private ByteBuf encodeMessageAs(ByteBuffer payload, PayloadType payloadType) throws WTPEncodingException {
59         if (payload == null) {
60             throw new WTPEncodingException("Payload is null");
61         }
62
63         final int payloadSize = payload.remaining();
64         if (payloadSize == 0) {
65             throw new WTPEncodingException("Payload is empty");
66         }
67
68         final ByteBuf encodedMessage = allocator.buffer(HEADER_SIZE + payloadSize);
69         writeBasicWTPFrameHeaderBeginning(encodedMessage);
70         writePayloadMessageHeaderEnding(encodedMessage, payloadType, payload, payloadSize);
71         return encodedMessage;
72     }
73
74     private void writeBasicWTPFrameHeaderBeginning(ByteBuf encodedMessage) {
75         encodedMessage.writeByte(MARKER_BYTE);
76         encodedMessage.writeByte(wireFrameVersion.major());
77         encodedMessage.writeByte(wireFrameVersion.minor());
78         encodedMessage.writeZero(RESERVED_BYTES_COUNT);
79     }
80
81     private void writePayloadMessageHeaderEnding(ByteBuf encodedMessage,
82                                                  PayloadType payloadType,
83                                                  ByteBuffer payload,
84                                                  int payloadSize) {
85         encodedMessage.writeBytes(payloadType.getPayloadTypeBytes());
86         encodedMessage.writeInt(payloadSize);
87         encodedMessage.writeBytes(payload);
88     }
89 }
90
91
92 class WTPEncodingException extends RuntimeException {
93     WTPEncodingException(String message) {
94         super(message);
95     }
96 }