Skip to content
Snippets Groups Projects
Commit 7b139871 authored by Komal Makkar's avatar Komal Makkar
Browse files

merged mastercd ..

parents 20950a67 72a6dc6b
No related branches found
No related tags found
1 merge request!15Integration tests Refactored
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.notification.provider.azure.models;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class HandshakeRequestData {
private String validationCode;
private String validationUrl;
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.notification.provider.azure.models;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class NotificationData {
private String data;
private Map<String,String> attributes;
private String messageId;
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.notification.provider.azure.models;
import com.google.gson.JsonObject;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class NotificationRequest {
private String id;
private String eventType;
private String subject;
private JsonObject data;
private String eventTime;
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.notification.provider.azure.pubsub;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.notification.provider.azure.models.HandshakeRequestData;
import org.opengroup.osdu.notification.provider.azure.models.NotificationData;
import org.opengroup.osdu.notification.provider.azure.models.NotificationRequest;
import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.Base64;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
// TODO : Make error messages as constants.
// TODO : Add TracePoints to exception logs so that monitoring is done well.
@Component
@RequestScope
public class EventGridRequestBodyExtractor implements IPubsubRequestBodyExtractor {
private static final String INVALID_EVENTGRID_MESSAGE = "Invalid Event Grid Message";
private static final String SUBSCRIPTION_ID = "Aeg-Subscription-Name";
private static final String EVENTGRID_VALIDATION_EVENT = "Microsoft.EventGrid.SubscriptionValidationEvent";
private static final Gson GSON = new Gson();
private static final ObjectMapper objectMapper = new ObjectMapper();
private JsonObject root = null;
private HttpServletRequest httpServletRequest;
private JaxRsDpsLog log;
private NotificationRequest notificationRequest;
private NotificationData notificationData;
private HandshakeRequestData handshakeRequestData;
private boolean isHandshakeRequest;
@Autowired
public EventGridRequestBodyExtractor(HttpServletRequest httpServletRequest, JaxRsDpsLog log) {
this.httpServletRequest = httpServletRequest;
this.log = log;
this.notificationRequest = extractNotificationRequestFromHttpRequest();
}
/**
* Extracts the attributes from the request that are filled in by publisher of the message.
*
* @throws AppException
* @return Request Attributes Map
*/
public Map<String, String> extractAttributesFromRequestBody() {
if(isHandshakeRequest) {
return null;
}
return this.notificationData.getAttributes();
}
/**
* Extracts the data from the request that are filled in by publisher of the message,
*
* @throws AppException
* @return Request Data String
*/
public String extractDataFromRequestBody() {
if(isHandshakeRequest) {
return null;
}
return new String(Base64.getDecoder().decode(notificationData.getData()));
}
/**
* Extracts the notificationId from the request that are filled in by EventGrid.
*
* @throws AppException
* @return Request NotificationId String.
*/
public String extractNotificationIdFromRequestBody() {
String subscriptionId = httpServletRequest.getHeader(SUBSCRIPTION_ID);
if (Strings.isNullOrEmpty(subscriptionId)) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), "Invalid Event Grid Message", "Subscription ID not found");
}
return subscriptionId;
}
/**
* Checks if the request is for handshake.
*
* @throws AppException
* @return Request Type Boolean
*/
public boolean isHandshakeRequest() {
return this.isHandshakeRequest ;
}
/**
* Return ValidationCode
*
* @throws AppException
* @return Request Type Boolean
*/
public String getValidationCodeForHandshake() {
if(!isHandshakeRequest) {
return null;
}
return this.handshakeRequestData.getValidationCode();
}
/**
* Utility method that extracts the core content in the request.
* This is what the publisher will publish.
*
* The attributes are validated.
*
* @throws AppException
* @return NotificationRequest Object
*/
private NotificationRequest extractNotificationRequestFromHttpRequest() {
NotificationRequest notificationRequest = null;
if (this.notificationRequest == null) {
try {
BufferedReader reader = httpServletRequest.getReader();
Stream<String> lines = reader.lines();
String requestBody = lines.collect(Collectors.joining("\n"));
NotificationRequest[] notificationRequestArray = GSON.fromJson(requestBody, NotificationRequest[].class);
notificationRequest = notificationRequestArray[0];
this.isHandshakeRequest = notificationRequest.getEventType().equals(EVENTGRID_VALIDATION_EVENT);
if (isHandshakeRequest) {
extractHandshakeData(notificationRequest);
} else {
extractNotificationData(notificationRequest);
}
} catch (Exception e) {
throw new AppException(HttpStatus.BAD_REQUEST.value(), "Request payload parsing error",
"Unable to parse request payload.", "Request contents are null or empty");
}
}
return notificationRequest;
}
private void extractHandshakeData(NotificationRequest notificationRequest) {
this.handshakeRequestData = GSON.fromJson(notificationRequest.getData(), HandshakeRequestData.class);
Preconditions.checkNotNull(this.handshakeRequestData.getValidationCode(), "Request payload parsing error" );
}
private void extractNotificationData(NotificationRequest notificationRequest) {
NotificationData notificationData = GSON.fromJson(notificationRequest.getData(), NotificationData.class);
verifyNotificationData(notificationData);
this.notificationData = notificationData;
}
// TODO: Clean up for using @NonNull Lombok.
// The Gson deserialisation happens through constructor made out of reflection,
// The unsafe initialisation inspires us to use Jackson
//
// Making Gson use a custom constructor, involves boilerplating, hence adding precondition checks. https://github.com/google/gson/blob/master/UserGuide.md#TOC-Writing-a-Deserializer
// The required condition is not operation as of now.https://github.com/google/gson/issues/61
private void verifyNotificationData(NotificationData notificationData) {
Preconditions.checkNotNull(notificationData, "Request payload parsing error" );
Preconditions.checkNotNull(notificationData.getData(), "Request payload parsing error" );
Preconditions.checkNotNull(notificationData.getMessageId(), "Request payload parsing error" );
Preconditions.checkNotNull(notificationData.getAttributes().get("correlation-id") , "Request payload parsing error" );
Preconditions.checkNotNull(notificationData.getAttributes().get("data-partition-id") , "Request payload parsing error" );
}
}
\ No newline at end of file
......@@ -15,10 +15,8 @@
package org.opengroup.osdu.notification.provider.azure.util;
import com.azure.cosmos.CosmosClient;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
import org.opengroup.osdu.azure.KeyVaultFacade;
import org.opengroup.osdu.notification.provider.interfaces.IAppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment