Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6eb7e19
Add the functionality for video call consultation service
vanitha1822 Mar 26, 2025
0a4b0ae
Add the necessary imports for the application
vanitha1822 Mar 29, 2025
7238a37
Update video call service with DB changes
vanitha1822 Apr 7, 2025
8471f97
Add update api for call status updation
vanitha1822 Apr 10, 2025
e12a949
Merge branch 'develop' of https://github.com/PSMRI/Common-API into nd…
vanitha1822 Apr 14, 2025
382c740
Add service class to prepare the sms template and include benregid
vanitha1822 Apr 28, 2025
6a9b599
update the properties in common_example file
vanitha1822 Apr 28, 2025
9ba1e10
Fix the issue in date time conversion
vanitha1822 Apr 28, 2025
e89b831
Add the link generated time and islinkused flag for the meeting link
vanitha1822 May 9, 2025
38c338a
Change the consultation date format and response format for send link…
vanitha1822 May 27, 2025
f685234
Add the video call url properties in environment files
vanitha1822 May 27, 2025
7bbad5c
Resolved the conflicts
vanitha1822 May 27, 2025
960f7d4
Add recording functionality
vanitha1822 Jun 18, 2025
5b36af4
feat:Merge with develop
vanitha1822 Jun 19, 2025
18e1d2a
Remove dev and test properties as it not in develop
vanitha1822 Jun 19, 2025
9f596e5
feat:fix the alignment
vanitha1822 Jun 19, 2025
5c92dbd
feat:remove cross origins and add variable name for ci file
vanitha1822 Jun 19, 2025
5e8e761
Add the properties in docker file
vanitha1822 Jun 19, 2025
bae01d9
Add recording properties in properties file
vanitha1822 Jun 19, 2025
e8e4ab8
fix:coderabbit comments
vanitha1822 Jun 19, 2025
b681ad4
Fix the build error
vanitha1822 Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/main/environment/common_ci.properties
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,6 @@ captcha.enable-captcha=@env.ENABLE_CAPTCHA@

cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS@



video-call-url=@env.VIDEO_CALL_URL@
jibri.output.path=@env.JIBRI_OUTPUT_PATH@
video.recording.path=@env.VIDEO_RECORDING_PATH@
6 changes: 5 additions & 1 deletion src/main/environment/common_docker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,8 @@ captcha.secret-key=${CAPTCHA_SECRET_KEY}
captcha.verify-url=${CAPTCHA_VERIFY_URL}
captcha.enable-captcha=${ENABLE_CAPTCHA}

cors.allowed-origins=${CORS_ALLOWED_ORIGINS}
cors.allowed-origins=${CORS_ALLOWED_ORIGINS}

video-call-url=${VIDEO_CALL_URL}
jibri.output.path={JIBRI_OUTPUT_PATH}
video.recording.path={VIDEO_RECORDING_PATH}
Comment on lines +183 to +185
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix environment variable placeholder syntax.
jibri.output.path and video.recording.path are missing the $ prefix. They should be ${JIBRI_OUTPUT_PATH} and ${VIDEO_RECORDING_PATH}.

Apply this diff:

- jibri.output.path={JIBRI_OUTPUT_PATH}
- video.recording.path={VIDEO_RECORDING_PATH}
+ jibri.output.path=${JIBRI_OUTPUT_PATH}
+ video.recording.path=${VIDEO_RECORDING_PATH}
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
video-call-url=${VIDEO_CALL_URL}
jibri.output.path={JIBRI_OUTPUT_PATH}
video.recording.path={VIDEO_RECORDING_PATH}
video-call-url=${VIDEO_CALL_URL}
jibri.output.path=${JIBRI_OUTPUT_PATH}
video.recording.path=${VIDEO_RECORDING_PATH}
πŸ€– Prompt for AI Agents
In src/main/environment/common_docker.properties around lines 183 to 185, the
environment variable placeholders for jibri.output.path and video.recording.path
are missing the $ prefix. Fix this by changing {JIBRI_OUTPUT_PATH} to
${JIBRI_OUTPUT_PATH} and {VIDEO_RECORDING_PATH} to ${VIDEO_RECORDING_PATH} to
correctly reference the environment variables.

12 changes: 8 additions & 4 deletions src/main/environment/common_example.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ cti-server-ip=10.208.122.99
cti-logger_base_url=http://10.208.122.99/logger

# Identity Config
identity-api-url = http://localhost:8094/
identity-api-url = http://localhost:8094
#Verify whether 1097 and identity are same?
identity-1097-api-url = http://localhost:8095/
identity-1097-api-url = http://localhost:8095
##Generate Benificiary Config
genben-api=http://localhost:8092/
genben-api=http://localhost:8092

#### SMS Configuration
send-sms=false
sendSMSUrl = http://localhost:8080/sms/sendSMS
sendSMSUrl = http://localhost:8083/sms/sendSMS
source-address=AIDSHL
sms-username=<Enter SMS username>
sms-password=<Enter SMS password>
Expand Down Expand Up @@ -198,6 +198,10 @@ grievanceAllocationRetryConfiguration=3
logging.path=logs/
logging.file.name=logs/common-api.log

video-call-url=https://vc.piramalswasthya.org/
jibri.output.path=/srv/jibri/recordings
video.recording.path=/srv/recordings

captcha.secret-key= <Enter Cloudflare Secret Key>
captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify
captcha.enable-captcha=true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.iemr.common.controller.videocall;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.iemr.common.model.videocall.UpdateCallRequest;
import com.iemr.common.model.videocall.VideoCallRequest;
import com.iemr.common.service.videocall.VideoCallService;
import com.iemr.common.utils.response.OutputResponse;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestBody;

@RestController
@RequestMapping(value = "/video-consultation")
public class VideoCallController {
final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

@Autowired
private VideoCallService videoCallService;

@PostMapping(value = "/generate-link", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
public ResponseEntity<Map<String, String>> generateJitsiLink() {
Map<String, String> response = new HashMap<>();
try {
String link = videoCallService.generateMeetingLink();
response.put("meetingLink", link);
return ResponseEntity.ok(response);
} catch (Exception e) {
response.put("error", e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
}

@PostMapping(value = "/send-link", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
public String sendVideoLink(@RequestBody String requestModel, HttpServletRequest request) {
OutputResponse response = new OutputResponse();

try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
VideoCallRequest requestData = objectMapper.readValue(requestModel, VideoCallRequest.class);
String serviceResponse = videoCallService.sendMeetingLink(requestData);

return serviceResponse;

} catch (Exception e) {
logger.error("send MeetingLink failed with error: " + e.getMessage(), e);
response.setError(e);
return response.toString();
}
}
Comment on lines +49 to +66
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Standardize response format and improve error handling.

This endpoint returns a raw String while other endpoints use ResponseEntity, creating inconsistency. Also, the exception handling could be more specific.

 @PostMapping(value = "/send-link", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
-public String sendVideoLink(@RequestBody String requestModel, HttpServletRequest request) {
-    OutputResponse response = new OutputResponse();
-
+public ResponseEntity<String> sendVideoLink(@RequestBody String requestModel, HttpServletRequest request) {
     try {
         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         VideoCallRequest requestData = objectMapper.readValue(requestModel, VideoCallRequest.class);
         String serviceResponse = videoCallService.sendMeetingLink(requestData);
         
-        return serviceResponse;
+        return ResponseEntity.ok(serviceResponse);
        
-    } catch (Exception e) {
+    } catch (JsonProcessingException e) {
+        logger.error("JSON parsing failed: " + e.getMessage(), e);
+        return ResponseEntity.badRequest().body("{\"status\":\"error\",\"message\":\"Invalid JSON format\"}");
+    } catch (Exception e) {
         logger.error("send MeetingLink failed with error: " + e.getMessage(), e);
-        response.setError(e);
-        return response.toString();
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+            .body("{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}");
     }
 }
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@PostMapping(value = "/send-link", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
public String sendVideoLink(@RequestBody String requestModel, HttpServletRequest request) {
OutputResponse response = new OutputResponse();
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
VideoCallRequest requestData = objectMapper.readValue(requestModel, VideoCallRequest.class);
String serviceResponse = videoCallService.sendMeetingLink(requestData);
return serviceResponse;
} catch (Exception e) {
logger.error("send MeetingLink failed with error: " + e.getMessage(), e);
response.setError(e);
return response.toString();
}
}
@PostMapping(value = "/send-link", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
public ResponseEntity<String> sendVideoLink(@RequestBody String requestModel, HttpServletRequest request) {
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
VideoCallRequest requestData = objectMapper.readValue(requestModel, VideoCallRequest.class);
String serviceResponse = videoCallService.sendMeetingLink(requestData);
return ResponseEntity.ok(serviceResponse);
} catch (JsonProcessingException e) {
logger.error("JSON parsing failed: " + e.getMessage(), e);
return ResponseEntity.badRequest()
.body("{\"status\":\"error\",\"message\":\"Invalid JSON format\"}");
} catch (Exception e) {
logger.error("send MeetingLink failed with error: " + e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}");
}
}
πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/common/controller/videocall/VideoCallController.java
lines 49 to 66, the sendVideoLink method returns a raw String instead of a
ResponseEntity, causing inconsistency with other endpoints. To fix this, change
the return type to ResponseEntity<String> and wrap the successful
serviceResponse in ResponseEntity.ok(). Also, replace the generic Exception
catch with more specific exceptions related to JSON parsing and service errors,
and return appropriate ResponseEntity with error status and message for better
error handling.


@PostMapping(value = "/update-call-status", produces = MediaType.APPLICATION_JSON_VALUE, headers = "Authorization")
public ResponseEntity<String> updateCallStatus(@RequestBody UpdateCallRequest requestModel, HttpServletRequest request) {
OutputResponse response = new OutputResponse();

try {
if (requestModel.getMeetingLink() == null || requestModel.getCallStatus() == null) {
throw new IllegalArgumentException("Meeting Link and Status are required");
}

String result = videoCallService.updateCallStatus(requestModel);

JSONObject responseObj = new JSONObject();
responseObj.put("status", "success");
responseObj.put("message", result);
response.setResponse(responseObj.toString());

} catch (IllegalArgumentException e) {
logger.error("Validation error: " + e.getMessage(), e);
return ResponseEntity.badRequest().body("{\"status\":\"error\",\"message\":\"" + e.getMessage() + "\"}");
} catch (Exception e) {
logger.error("updateCallStatus failed with error: " + e.getMessage(), e);
response.setError(e);
}

return ResponseEntity.ok(response.toString());
}



}
14 changes: 9 additions & 5 deletions src/main/java/com/iemr/common/data/sms/SMSParametersMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import java.sql.Timestamp;

import com.iemr.common.utils.mapper.OutputMapper;

import com.google.gson.GsonBuilder;
import com.google.gson.LongSerializationPolicy;
import com.google.gson.annotations.Expose;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -69,9 +71,11 @@ public class SMSParametersMap
@Column(name = "LastModDate", insertable = false, updatable = false)
Timestamp lastModDate;

@Override
public String toString()
{
return OutputMapper.gsonWithoutExposeRestriction().toJson(this);
@Override
public String toString() {

return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setLongSerializationPolicy(LongSerializationPolicy.STRING).serializeNulls()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create().toJson(this);
}

}
10 changes: 7 additions & 3 deletions src/main/java/com/iemr/common/data/sms/SMSTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import com.iemr.common.utils.mapper.OutputMapper;

import com.google.gson.GsonBuilder;
import com.google.gson.LongSerializationPolicy;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand Down Expand Up @@ -77,8 +79,10 @@ public class SMSTemplate
Timestamp lastModDate;

@Override
public String toString()
{
return OutputMapper.gsonWithoutExposeRestriction().toJson(this);
public String toString() {

return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setLongSerializationPolicy(LongSerializationPolicy.STRING).serializeNulls()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create().toJson(this);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.iemr.common.data.videocall;

import java.sql.Timestamp;

import com.iemr.common.utils.mapper.OutputMapper;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "t_videocallparameter")
@Data
public class VideoCallParameters {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MeetingID")
private Integer meetingID;

@Column(name = "DateOfCall")
private Timestamp dateOfCall;

@Column(name = "CallerPhoneNumber")
private String callerPhoneNumber;

@Column(name = "AgentID")
private String agentID;

@Column(name = "AgentName")
private String agentName;

@Column(name = "MeetingLink")
private String meetingLink;

@Column(name = "CallStatus")
private String callStatus;

@Column(name = "CallDuration")
private String callDuration;

@Column(name = "ProviderServiceMapID")
private Integer providerServiceMapID;

@Column(name = "BeneficiaryRegID")
private Long beneficiaryRegID;

@Column(name = "ClosureRemark")
private String closureRemark;

@Column(name = "LinkGeneratedAt")
private Timestamp linkGeneratedAt;

@Column(name = "IsLinkUsed")
private boolean linkUsed;

@Column(name = "Deleted", insertable = false, updatable = true)
private Boolean deleted;

@Column(name = "CreatedBy", insertable = true, updatable = false)
private String createdBy;

@Column(name = "CreatedDate", insertable = false, updatable = false)
private Timestamp createdDate;

@Column(name = "ModifiedBy", insertable = false, updatable = true)
private String modifiedBy;

@Column(name = "LastModDate", insertable = false, updatable = false)
private Timestamp lastModDate;

@Override
public String toString()
{
return OutputMapper.gsonWithoutExposeRestriction().toJson(this);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/iemr/common/mapper/sms/SMSMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface SMSMapper

SMSMapper INSTANCE = Mappers.getMapper(SMSMapper.class);

@Mappings({ @Mapping(source = "request.smsTemplateTypeID", target = "smsTypeID"), })
@Mappings({ @Mapping(source = "request.smsTemplateTypeID", target = "smsTypeID") })
SMSTemplate requestToSMSTemplate(SMSRequest request);

@IterableMapping(elementTargetType = SMSTemplate.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.iemr.common.mapper.videocall;

import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.mapstruct.IterableMapping;
import org.mapstruct.factory.Mappers;

import com.iemr.common.data.videocall.VideoCallParameters;
import com.iemr.common.model.videocall.UpdateCallRequest;
import com.iemr.common.model.videocall.UpdateCallResponse;
import com.iemr.common.model.videocall.VideoCallRequest;

@Mapper(componentModel = "spring")
public interface VideoCallMapper {
VideoCallMapper INSTANCE = Mappers.getMapper(VideoCallMapper.class);

VideoCallRequest videoCallToRequest(VideoCallParameters videoCall);

VideoCallParameters videoCallToEntity(VideoCallRequest videoCallRequest);

@IterableMapping(elementTargetType = VideoCallRequest.class)
List<VideoCallRequest> videoCallToRequestList(List<VideoCallParameters> videoCallList);

@IterableMapping(elementTargetType = VideoCallParameters.class)
List<VideoCallParameters> videoCallToEntityList(List<VideoCallRequest> videoCallRequestList);

VideoCallParameters updateRequestToVideoCall(UpdateCallRequest updateCallStatusRequest);

UpdateCallResponse videoCallToResponse(VideoCallParameters videoCall);

@IterableMapping(elementTargetType = VideoCallParameters.class)
List<VideoCallParameters> updateRequestToVideoCall(List<UpdateCallRequest> updateCallStatusRequests);

@IterableMapping(elementTargetType = UpdateCallResponse.class)
List<UpdateCallResponse> videoCallToResponse(List<VideoCallParameters> videoCalls);
}
4 changes: 3 additions & 1 deletion src/main/java/com/iemr/common/model/sms/SMSRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import java.sql.Timestamp;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.iemr.common.data.telemedicine.PrescribedDrugDetail;

import lombok.Data;
Expand Down Expand Up @@ -78,4 +78,6 @@ public class SMSRequest {
private Long beneficiaryId;
private String appointmentDate;
private String appointmentTime;
@JsonProperty("sms_Advice")
private String smsAdvice;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.iemr.common.model.videocall;

import lombok.Data;

@Data
public class UpdateCallRequest {

private String meetingLink;
private String callStatus;
private String callDuration;
private String modifiedBy;
}
Comment on lines +1 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Add validation and improve type safety for the DTO.

The UpdateCallRequest class would benefit from the following enhancements:

  1. Input validation: Add validation annotations for required fields and format constraints
  2. Type safety: Consider using more specific types for duration
  3. Documentation: Add class and field-level JavaDoc
 package com.iemr.common.model.videocall;

+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
 import lombok.Data;

+/**
+ * Request model for updating video call status and details
+ */
 @Data
 public class UpdateCallRequest {
 	
+	@NotBlank(message = "Meeting link is required")
 	private String meetingLink;
+	
+	@NotBlank(message = "Call status is required")
+	@Pattern(regexp = "^(INITIATED|IN_PROGRESS|COMPLETED|CANCELLED)$", 
+		message = "Invalid call status")
 	private String callStatus; 
+	
 	private String callDuration; 
+	
+	@NotBlank(message = "Modified by is required")
 	private String modifiedBy;
 }
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
package com.iemr.common.model.videocall;
import lombok.Data;
@Data
public class UpdateCallRequest {
private String meetingLink;
private String callStatus;
private String callDuration;
private String modifiedBy;
}
package com.iemr.common.model.videocall;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
/**
* Request model for updating video call status and details
*/
@Data
public class UpdateCallRequest {
@NotBlank(message = "Meeting link is required")
private String meetingLink;
@NotBlank(message = "Call status is required")
@Pattern(regexp = "^(INITIATED|IN_PROGRESS|COMPLETED|CANCELLED)$",
message = "Invalid call status")
private String callStatus;
private String callDuration;
@NotBlank(message = "Modified by is required")
private String modifiedBy;
}
πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/common/model/videocall/UpdateCallRequest.java lines 1
to 12, enhance the UpdateCallRequest class by adding validation annotations such
as @NotNull or @NotBlank for required fields and format constraints where
applicable. Replace the callDuration String with a more specific type like
Duration or an appropriate numeric type to improve type safety. Additionally,
add JavaDoc comments at the class level and for each field to document their
purpose and usage clearly.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.iemr.common.model.videocall;

import java.sql.Timestamp;

import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.Data;

@Data
public class UpdateCallResponse {
private String meetingLink;
private String callStatus;
private String callDuration;
private String modifiedBy;
private boolean isLinkUsed;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
private Timestamp lastModified;

public UpdateCallResponse() {
}
}
Loading