Implemented most of logic behind REST Mock Services

Added dev.sh script to run r11-tools in dev-mode with hot-reload for frontend
This commit is contained in:
2023-06-19 15:31:15 +02:00
parent c0fcd53d35
commit 3a3073d236
9 changed files with 177 additions and 48 deletions

View File

@@ -36,14 +36,12 @@ public class MockController {
/**
* Updates queried message with given set of data
* @param body {@link MockedMessageDto} json representation
* @param message {@link MockedMessageDto} json representation
* @return confirmation and 200 OK
*/
@SneakyThrows
@PutMapping
public ResponseEntity<String> updateMessage(@RequestBody String body){
ObjectMapper mapper = new ObjectMapper();
MockedMessageDto message = mapper.readValue(body, MockedMessageDto.class);
public ResponseEntity<String> updateMessage(@RequestBody MockedMessageDto message){
return klausService.setMockedResponse(message);
}

View File

@@ -1,34 +1,42 @@
<script setup>
import {ref} from 'vue';
<script setup lang="ts">
import { ref} from 'vue';
const props = defineProps(
{
headersObject : Object
}
)
const headerData = ref( props.headersObject )
const emit = defineEmits([
'update:httpHeaders'
])
const headerData = ref(props.headersObject)
const newHeaderName = ref('');
const newHeaderValue = ref('');
function isHeaderEssential(headerName){
function isHeaderEssential(headerName : string){
return headerName == "Keep-Alive" || headerName == "Connection" || headerName == "Date"
}
function setEssentialHeaderStyle(headerName){
return isHeaderEssential(headerName) ? "text-gray-400" : "text-red-400";
function setEssentialHeaderStyle(headerName : string){
return isHeaderEssential(headerName) ? "text-gray-400" : "text-red-400";
}
function deleteHeader(index){
if(!isHeaderEssential(index)){
function deleteHeader(index : string){
if(!isHeaderEssential(index) && headerData.value != undefined){
delete headerData.value[index]
emit('update:httpHeaders',headerData.value)
}
}
function addNewHeader(name, value){
headerData.value[name] = value;
newHeaderName.value = "";
newHeaderValue.value = "";
function addNewHeader(name : string, value : string){
if (headerData.value != undefined){
headerData.value[name] = value;
newHeaderName.value = "";
newHeaderValue.value = "";
emit('update:httpHeaders',headerData.value)
}
}
</script>

View File

@@ -0,0 +1,49 @@
<script setup lang="ts">
import { ref, type Ref } from 'vue';
interface historyRecord {
clientUUID : String,
dateTimeStamp: String,
headers : Object,
httpMethod: String,
requestBody: String
}
const clientUUID = localStorage.getItem("clientUUID")
const fetchLink = window.location.protocol + "//" + window.location.hostname + "/mock/api/event";
const historyRecords : Ref<Array<historyRecord>> = ref([])
fetch(fetchLink+"/"+clientUUID).then(response => response.json()).then(data => { historyRecords.value = data });
function parseTimeStamp(timestamp : String){
return timestamp.substring(10,19).replace("T"," ");
}
function showHeaders(headers:Object){
}
function showBody(body : String){
}
</script>
<template>
<table class="text-white h-28 w-5/12 text-center border-l-4 border-b-2">
<tr>
<th>Time</th>
<th>HTTP Method</th>
<th>HTTP Headers</th>
<th>Request Body</th>
</tr>
<tr v-for="(item , index) in historyRecords" :key="index">
<td> {{ parseTimeStamp(item.dateTimeStamp) }} </td>
<td> {{ item.httpMethod }} </td>
<td> <button @click="showHeaders(item.headers);">Show Headers</button> </td>
<td> <button @click="showBody(item.requestBody)">Show Body</button> </td>
</tr>
</table>
</template>

View File

@@ -0,0 +1,36 @@
<script setup lang="ts">
import { ref} from 'vue';
const emit = defineEmits([
'closed:toast_closed'
])
const props = defineProps(
{
message: {type: String, required: true},
visible: {type: String, required: true},
}
)
function hideToast(){
emit('closed:toast_closed',"hidden")
}
</script>
<template>
<div id="toast-success" :class="visible" class="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800" role="alert">
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200">
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path></svg>
<span class="sr-only">Check icon</span>
</div>
<div class="ml-3 text-sm font-normal">{{ props.message }}</div>
<button @click="hideToast" type="button" class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700">
<span class="sr-only">Close</span>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
</div>
</template>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import {ref, onBeforeMount , type Ref} from 'vue';
import {ref, type Ref} from 'vue';
import HeadersComponent from './HeadersComponent.vue';
import SaveComponent from './SaveComponent.vue';
const clientUUID = ref('');
const host = window.location.protocol + "//" + window.location.hostname + "/mock";
@@ -21,15 +22,12 @@ const exampleData : mockedMessageData = {
httpHeaders: {Connection:"keep-alive"},
httpStatus: 200,
}
let messageData : Ref<mockedMessageData> = ref(exampleData) ;
onBeforeMount( () => {
if ( localStorage.clientUUID != undefined ){
let messageData : Ref<mockedMessageData> = ref(exampleData);
if ( localStorage.clientUUID != undefined ){
clientUUID.value = localStorage.clientUUID;
}
fetch(host + '/api/mock/' + clientUUID.value).then( response => response.json() ).then(data => putDataInFields(data));
} )
}
fetch(host + '/api/mock/' + clientUUID.value).then( response => response.json() ).then(data => {putDataInFields(data); });
function putDataInFields(data: mockedMessageData){
clientUUID.value = data.clientUUID;
@@ -41,28 +39,33 @@ function putDataInFields(data: mockedMessageData){
</script>
<template>
<div class="flex flex-col w-3/5 text-center gap-6">
<div class="flex flex-col w-3/5 text-center dark:text-white gap-6">
<div>
<label for="link">Link</label><br/>
<div class="p-2 border-white border-2">
<a class="underline" :href="mockMessageLink">{{ mockMessageLink }}</a>
</div>
<div class="flex gap-4">
<div class="p-2 w-full border-white border-2">
<a class="underline" :href="mockMessageLink">{{ mockMessageLink }}</a>
</div>
<SaveComponent v-bind:message-data="messageData"></SaveComponent>
</div>
</div>
<div class="flex flex-row w-full gap-64">
<div class="w-full">
<label for="contentType">Content Type</label><br/>
<input class="bg-gray-600 w-full" id="contentType" type="text" :value="messageData.contentType"/>
<input class="bg-gray-600 w-full" id="contentType" type="text" v-model="messageData.contentType"/>
</div>
<div class=" w-full">
<div class="w-full">
<label for="httpStatus">HttpStatus</label><br/>
<input class="bg-gray-600 w-full" id="httpStatus" type="text" :value="messageData.httpStatus"/>
<input class="bg-gray-600 w-full" id="httpStatus" type="text" v-model="messageData.httpStatus"/>
</div>
</div>
<div class="flex flex-col">
<label for="messageBody">Body</label>
<textarea class="bg-gray-600 h-64" id="messageBody" :value="messageData.messageBody.toString()"></textarea>
<textarea class="bg-gray-600 h-64" id="messageBody" v-model="messageData.messageBody"></textarea>
</div>
<HeadersComponent :key="JSON.stringify(messageData.httpHeaders)" :headers-object="messageData.httpHeaders"></HeadersComponent>
<HeadersComponent @update:httpHeaders="(newHeaders: object) => {messageData.httpHeaders = newHeaders }" :key="JSON.stringify(messageData.httpHeaders)" :headers-object="messageData.httpHeaders"></HeadersComponent>
</div>
</template>

View File

@@ -0,0 +1,45 @@
<script setup lang="ts">
import { ref } from 'vue';
import MockedMessageToastComponent from './MockedMessageToastComponent.vue';
const props = defineProps(
{
messageData : {type: Object, required:true}
}
)
const message = ref('');
const visible = ref('hidden');
const fetchLink = window.location.protocol + "//" + window.location.hostname + "/mock/api/mock"
function prepareAndSendData(){
if (props.messageData != null|| props.messageData != undefined ){
fetch(fetchLink, { method: "put", body:JSON.stringify(props.messageData), headers: { "Content-Type" : "application/json" }})
.then( response => response.text() )
.then( data => {message.value = data} )
.catch(exception => {message.value = exception})
showToast();
}
}
function showToast(){
visible.value = "visible";
}
function hideToast(){
visible.value = "hidden";
}
</script>
<template>
<button @click="prepareAndSendData()" class="w-2/12 tool-button">Save</button>
<div class="fixed bottom-5 right-12">
<MockedMessageToastComponent @closed:toast_closed="hideToast()" v-bind:visible="visible" v-bind:message="message"/>
</div>
</template>

View File

@@ -34,11 +34,6 @@ const routes = [
name: 'xslt',
component: () => xsltTool
},
{
path: '/xml/xpath',
name: 'xpath',
component: () => restMock
},
{
path: '/rest/mock',
name: 'restmock',

View File

@@ -1,20 +1,14 @@
<script lang="ts">
<script setup lang="ts">
import RestMockMessageComponent from '@components/mock/RestMockMessageComponent.vue'
import mockedMessageData from '@components/mock/RestMockMessageComponent.vue'
export default {
name:"RestMockView",
components: {RestMockMessageComponent}
}
import HistoryComponent from '@components/mock/HistoryComponent.vue'
</script>
<template>
<div class="flex w-full h-screen items-center flex-col">
<div class="flex gap-6 w-full h-screen">
<RestMockMessageComponent></RestMockMessageComponent>
<HistoryComponent></HistoryComponent>
</div>
</template>

1
dev.sh Executable file
View File

@@ -0,0 +1 @@
docker-compose -f docker-compose.dev.yml up --build