Microservices- Architecture

Microservices – Architecture Example Application

We are going to build a simple Microservices application and assume we are going to start with the following microservices:

  1. EDC-Microservice: Electronic Data Capture (EDC) system is software that stores patient data collected in clinical trials.It provides REST API to provide Electronic Data Capture functionalities.

    1. TestReports

    2. MedicalHistory

    3. Visit Reports

  2. MI- Microservice : Medical imaging systems give health-care providers and researchers the information they need using high-frequency sound waves (ultrasound and echocardiography), magnetic fields (MRI), and electromagnetic radiation (conventional 2-D X-ray, 3-D computed tomography or CT scan, and fluoroscopy).

  • RadiographyReports,

  • computed tomography (CT Scan Reports),

  • magnetic resonance imaging (MRI),

  • ultrasound,DentalScanReports

  1. RTSM – Microservice Randomization and Trial Supply Management system, is responsible for enabling critical functions of a clinical trial, from randomizing patients (who gets the active drug vs. the placebo), dispensing drug (ensuring patients receive the correct dose) and site resupply (controls the flow of drug from the manufacturer to the depot to the clinical site).

  2. UserManagent-ui: It is customer facing front-end web application.

We are going to build various services and REST endpoints through various microservice concepts.

a.EDC-MicroService

Create a SpringBoot app with Web, JPA, MySQL, Actuator, DevTools, Lombok starters

Database : MySQL as Docker Container

We are going to use Docker and run MySQL as a Docker container.

docker-compose.yml

version: '3'
services:
  mysqldb:
    image: 'mysql:5.7'
    container_name: mysqldb
    ports:
      - '3306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: passw0rd
      MYSQL_DATABASE: catalog

Download & Start MySQL Docker container

docker-compose up

Open any MySQL Editor & provide login details

application.properties

spring.application.name=EDC-MicroService
server.servlet.context-path=/edc
server.port=8031
 
spring.datasource.url= jdbc:mysql://localhost:3306/microservices?useSSL=false
spring.datasource.username= root
spring.datasource.password= root
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update

# springdoc.swagger-ui.path=/swagger-ui.html

# Azure KeyValut Server
# azure.keyvault.enabled=true
# azure.keyvault.uri=https://idamtestvalut.vault.azure.net/
# azure.keyvault.client-id=put-your-azure-client-id-here
# azure.keyvault.client-key=put-your-azure-client-key-here

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
management.endpoints.web.exposure.include=*

spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1


# Consumer properties
spring.kafka.producer.bootstrap-servers=127.0.0.1:9092
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.group-id=group_id
topic.name.consumer=user.provision.topic

# Common Kafka Properties
auto.create.topics.enable=true


azure.activedirectory.session-stateless=true
azure.activedirectory.client-id=D4N7Q~uBPMd~NIsUp8VYxX4-vFnpOZFqfWdPo
azure.activedirectory.appIdUri=http://localhost:3000/
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://login.windows.net/common/discovery/keys
logging.level.org.springframework.security=DEBUG

spring.jackson.serialization.fail-on-empty-beans=false

Java Code

@Entity
@Table(name = "edc_testreports")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class TestReport {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	Integer id;
	
	@Column
	String reportName;
	
	@Column
	String reportType;
	
	@Column
	String trialId;
	
	@Column
	String trialName; 
	
	@Column
	private String userId;

}

@Repository
public interface TestReportRepository extends JpaRepository<TestReport, Integer>{

}
package com.edc.controller;

@CrossOrigin(origins = "http://localhost:3000")
@RestController
public class TestReportController {

	@Autowired
	TestReportRepository repository;
	
	@Autowired
	RestTemplate restTemplate;
	
	@RequestMapping(value = "/", produces = "text/html")
	public ResponseEntity<String> dashboard() {
		String bodyStr = homePageData();
		return ResponseEntity.ok().body(bodyStr);
	}
	

	@GetMapping("/testReport/{id}")
	public ResponseEntity<TestReport> getReportByID(@PathVariable int id){	
		
		TestReport data = repository.getById(id);
		System.out.println("data : "+data);
		
		try {	
				return ResponseEntity
		        .ok()
		        .contentType(MediaType.APPLICATION_JSON)
		        .body(data);
		} catch (Exception e) {
			return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
		}
	}
	
	
	@GetMapping("/testReport/all")
	public ResponseEntity<List<TestReport>> getAllTestReports() {
		try {
			List<TestReport> reports = new ArrayList<TestReport>();
			repository.findAll().forEach(reports::add);
			System.out.println(reports.size());
			if (reports.isEmpty()) {
				return new ResponseEntity<>(HttpStatus.NO_CONTENT);
			}
			return new ResponseEntity<>(reports, HttpStatus.OK);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
	
	@PostMapping("/testReport/add")
	public ResponseEntity<TestReport> createReport(@RequestBody TestReport report) {
		try {
			TestReport testreport = repository.save(new TestReport(report.getReportName(), report.getReportType(), report.getTrialId(), report.getTrialName(), report.getUserId()));

			return ResponseEntity
			        .ok()
			        .contentType(MediaType.APPLICATION_JSON)
			        .body(testreport);	
			
			
		} catch (Exception e) {
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}	
	
	
	@GetMapping(value =  "/testReport/mi", produces = "application/json")
	public ResponseEntity<Object> getAllMIReportsNoramlcall() {
		try {			
ResponseEntity<Object> responseEntity =  restTemplate.getForEntity("http://MI-MICROSERVICE/mi/anthology/all", Object.class); 
			return new ResponseEntity<>(responseEntity, HttpStatus.OK);
		} catch (Exception e) {
			return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
  
	@GetMapping(value =  "/testReport/mihystrix", produces = "application/json")
       @HystrixCommand(fallbackMethod = "miReportFallBackMethod")
	public ResponseEntity<Object> getAllMIReportsWithHyStrix() { 
			ResponseEntity<Object> responseEntity =  restTemplate.getForEntity("http://MI-MICROSERVICE/mi/anthology/all", Object.class);
			System.out.println(responseEntity);			 
			return new ResponseEntity<>(responseEntity, HttpStatus.OK);
		 
	}
  
	public ResponseEntity<Object> miReportFallBackMethod() {					 
		return new ResponseEntity<>("MI Service is Not Avaialable", HttpStatus.OK);
	}
	
}