Go开发PaaS平台核心功能
代码仓库地址GitHub - yunixiangfeng/gopaas
10-18 中间件前端页面以及核心API开发(中)
C:\Users\Administrator\Desktop\gopaas\middlewareapi\handler\middlewareApiHandler.go
package handler
import (
"context"
"encoding/json"
"errors"
"strconv"
log "github.com/asim/go-micro/v3/logger"
"ithub.com/yunixiangfeng/gopaas/middlewareApi/plugin/form"
"github.com/yunixiangfeng/gopaas/common"
middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)
type MiddlewareApi struct{
MiddlewareService middleware.MiddlewareService
}
// middlewareApi.FindMiddlewareById 通过API向外暴露为/middlewareApi/findMiddlewareById,接收http请求
// 即:/middlewareApi/FindMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) FindMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.FindMiddlewareById request")
if _,ok:=req.Get["middle_id"];!ok{
return errors.New("参数异常!")
}
idString := req.Get["middle_id"].Values[0]
id,err := strconv.ParseInt(idString,10,64)
if err != nil {
common.Error(err)
return err
}
middleInfo,err:=e.MiddlewareService.FindMiddlewareByID(ctx,&middleware.MiddlewareId{Id:id})
rsp.StatusCode = 200
b, _ := json.Marshal(middleInfo)
rsp.Body = string(b)
return nil
}
// middlewareApi.AddMiddleware 通过API向外暴露为/middlewareApi/AddMiddleware,接收http请求
// 即:/middlewareApi/AddMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.AddMiddleware 方法
func (e *MiddlewareApi) AddMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.AddMiddleware request")
addMiddleInfo := &middleware.MiddlewareInfo{}
//设置端口
port,err := e.setMiddlePort(req)
if err != nil {
common.Error(err)
return err
}
addMiddleInfo.MiddlePort = port
//设置环境变量
addMiddleInfo.MiddleEnv = e.setMiddleEnv(req)
//设置存储
addMiddleInfo.MiddleStorage = e.setMiddleStorage(req)
//获取类型
middleTypeInfo := e.getMiddleType(req)
//判断不同的类型设置不同的值
switch middleTypeInfo.MiddleTypeName {
case "MYSQL":
middleConfig := e.setMiddleConfig(req)
addMiddleInfo.MiddleConfig = &middleConfig
}
//处理表单
form.FormToMiddlewareStruct(req.Post,addMiddleInfo)
//调用后端服务添加数据
response,err := e.MiddlewareService.AddMiddleware(ctx,addMiddleInfo)
if err != nil {
common.Error(err)
return err
}
rsp.StatusCode = 200
b, _ := json.Marshal(response)
rsp.Body = string(b)
return nil
}
//设置mysql config 设置
func (e *MiddlewareApi) setMiddleConfig(req *middlewareApi.Request)(middleConfig middleware.MiddleConfig) {
middleConfig.MiddleConfigRootUser = e.getValue(req,"middle_config_root_user")
middleConfig.MiddleConfigRootPwd = e.getValue(req,"middle_config_root_pwd")
middleConfig.MiddleConfigUser = e.getValue(req,"middle_config_user")
middleConfig.MiddleConfigPwd = e.getValue(req,"middle_config_pwd")
middleConfig.MiddleConfigDataBase = e.getValue(req,"middle_config_data_base")
return
}
file:///home/gopath/src/gopaas/go-paas-front/middleware-create.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="assets/img/logo-fav.png">
<title>CPaaS</title>
<link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
<link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
<link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
</head>
<body>
<div class="be-wrapper">
<nav class="navbar navbar-default navbar-fixed-top be-top-header">
<div class="container-fluid">
<div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
</div>
<div class="be-right-navbar">
<ul class="nav navbar-nav navbar-right be-user-nav">
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
<ul role="menu" class="dropdown-menu">
<li>
<div class="user-info">
<div class="user-name">wu123</div>
<div class="user-position online">在线</div>
</div>
</li>
<li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
<li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
<li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
</ul>
</li>
</ul>
<div class="page-title"></div>
<ul class="nav navbar-nav navbar-right be-icons-nav">
<li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
<ul class="dropdown-menu be-notifications">
<li>
<div class="title">消息提醒<span class="badge">3</span></div>
<div class="list">
<div class="be-scroller">
<div class="content">
<ul>
<li class="notification notification-unread"><a href="#">
<div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
<div class="notification-info">
<div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
</div></a></li>
<li class="notification"><a href="#">
<div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
<div class="notification-info">
<div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
</div></a></li>
<li class="notification"><a href="#">
<div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
<div class="notification-info">
<div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
</div></a></li>
<li class="notification"><a href="#">
<div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
<div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
</ul>
</div>
</div>
</div>
<div class="footer"> <a href="#">View all notifications</a></div>
</li>
</ul>
</li>
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
<ul class="dropdown-menu be-connections">
<li>
<div class="list">
<div class="content">
<div class="row">
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
</div>
<div class="row">
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
</div>
</div>
</div>
<div class="footer"> <a href="#">More</a></div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!--
侧边栏-开始
-->
<div class="be-left-sidebar">
<div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
<div class="left-sidebar-spacer">
<div class="left-sidebar-scroll">
<div class="left-sidebar-content">
<ul class="sidebar-elements">
<li class="divider">菜单</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
<ul class="sub-menu">
<li ><a href="pod-index.html">添加应用</a>
</li>
</ul>
</li>
<li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
<ul class="sub-menu">
<li ><a href="svc-index.html">添加服务</a>
</li>
</ul>
</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
<ul class="sub-menu">
<li ><a href="route-index.html">添加路由</a>
</li>
</ul>
</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>中间件</span></a>
<ul class="sub-menu">
<li class="active"><a href="middleware-create.html">创建中间件</a>
</li>
</ul>
</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
<ul class="sub-menu">
<li><a href="tables-general.html">General</a>
</li>
<li><a href="tables-datatables.html">Data Tables</a>
</li>
<li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
</li>
</ul>
</li>
<li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
<ul class="sub-menu">
<li><a href="pages-blank.html">Blank Page</a>
</li>
<li><a href="pages-blank-header.html">Blank Page Header</a>
</li>
<li><a href="pages-login.html">Login</a>
</li>
<li><a href="pages-login2.html">Login v2</a>
</li>
<li><a href="pages-404.html">404 Page</a>
</li>
<li><a href="pages-sign-up.html">Sign Up</a>
</li>
<li><a href="pages-forgot-password.html">Forgot Password</a>
</li>
<li><a href="pages-profile.html">Profile</a>
</li>
<li><a href="pages-pricing-tables.html">Pricing Tables</a>
</li>
<li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
</li>
<li><a href="pages-timeline.html">Timeline</a>
</li>
<li><a href="pages-timeline2.html">Timeline v2</a>
</li>
<li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
</li>
<li><a href="pages-calendar.html">Calendar</a>
</li>
<li><a href="pages-gallery.html">Gallery</a>
</li>
<li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
</li>
<li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
</li>
<li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="progress-widget">
<div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
<div class="progress">
<div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
</div>
</div>
</div>
</div>
<!--
侧边栏-结束
-->
<div class="be-content">
<div class="page-head">
<h2 class="page-head-title">中间件</h2>
<ol class="breadcrumb page-head-nav">
<li><a href="#">控制台</a></li>
<li><a href="#">中间件</a></li>
<li class="active">中间件列表</li>
</ol>
</div>
<div class="main-content container-fluid">
<div class="row pricing-tables">
<div class="col-md-3">
<div class="pricing-table pricing-table-primary">
<div class="pricing-table-image">
<img src="./assets/img/Consul.jpeg">
</div>
<div class="pricing-table-title">Consul</div>
<div class="panel-divider panel-divider-xl"></div>
<ul class="pricing-table-features">
<li>Consul 简化了分布式环境中的服务的注册和发现流程,通过 HTTP 或者 DNS 接口发现。支持外部 SaaS 提供者等。</li>
<li></li>
</ul><a href="#" class="btn btn-primary">开始创建</a>
</div>
</div>
<div class="col-md-3">
<div class="pricing-table pricing-table-primary">
<div class="pricing-table-image">
<img src="./assets/img/Mysql.jpeg">
</div>
<div class="pricing-table-title">Mysql</div>
<div class="panel-divider panel-divider-xl"></div>
<ul class="pricing-table-features">
<li>MySQL 是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,这样就增加了速度并提高了灵活性。
</li>
<li></li>
</ul><a href="middleware-create-mysql.html" class="btn btn-primary">开始创建</a>
</div>
</div>
<div class="col-md-3">
<div class="pricing-table pricing-table-primary">
<div class="pricing-table-image">
<img src="./assets/img/Redis.jpeg">
</div>
<div class="pricing-table-title">Redis</div>
<div class="panel-divider panel-divider-xl"></div>
<ul class="pricing-table-features">
<li>Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
</li>
<li></li>
</ul><a href="#" class="btn btn-primary">开始创建</a>
</div>
</div>
<div class="col-md-3">
<div class="pricing-table pricing-table-primary">
<div class="pricing-table-image">
<img src="./assets/img/MariaDB.jpeg">
</div>
<div class="pricing-table-title">MariaDB</div>
<div class="panel-divider panel-divider-xl"></div>
<ul class="pricing-table-features">
<li>MariaDB数据库管理系统是MySQL的一个分支, MariaDB的目的是完全兼容MySQL,使之能轻松成为MySQL的代替品。</li>
<li></li>
</ul><a href="#" class="btn btn-primary">开始创建</a>
</div>
</div>
</div>
</div>
</div>
<nav class="be-right-sidebar">
<div class="sb-content">
<div class="tab-navigation">
<ul role="tablist" class="nav nav-tabs nav-justified">
<li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
<li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
<li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
</ul>
</div>
<div class="tab-panel">
<div class="tab-content">
<div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
<div class="chat-contacts">
<div class="chat-sections">
<div class="be-scroller">
<div class="content">
<h2>Recent</h2>
<div class="contact-list contact-list-recent">
<div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
<div class="user-data"><span class="status away"></span><span class="name">Claire Sassu</span><span class="message">Can you share the...</span></div></a></div>
<div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
<div class="user-data"><span class="status"></span><span class="name">Maggie jackson</span><span class="message">I confirmed the info.</span></div></a></div>
<div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
<div class="user-data"><span class="status offline"></span><span class="name">Joel King </span><span class="message">Ready for the meeti...</span></div></a></div>
</div>
<h2>Contacts</h2>
<div class="contact-list">
<div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
<div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
<div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
<div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
<div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
<div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
</div>
</div>
</div>
</div>
<div class="bottom-input">
<input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
</div>
</div>
<div class="chat-window">
<div class="title">
<div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
<h2>Maggie jackson</h2><span>Active 1h ago</span>
</div><span class="icon return mdi mdi-chevron-left"></span>
</div>
<div class="chat-messages">
<div class="be-scroller">
<div class="content">
<ul>
<li class="friend">
<div class="msg">Hello</div>
</li>
<li class="self">
<div class="msg">Hi, how are you?</div>
</li>
<li class="friend">
<div class="msg">Good, I'll need support with my pc</div>
</li>
<li class="self">
<div class="msg">Sure, just tell me what is going on with your computer?</div>
</li>
<li class="friend">
<div class="msg">I don't know it just turns off suddenly</div>
</li>
</ul>
</div>
</div>
</div>
<div class="chat-input">
<div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
<input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
</div>
</div>
</div>
</div>
<div id="tab2" role="tabpanel" class="tab-pane tab-todo">
<div class="todo-container">
<div class="todo-wrapper">
<div class="be-scroller">
<div class="todo-content"><span class="category-title">Today</span>
<ul class="todo-list">
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo1" type="checkbox" checked="">
<label for="todo1">Initialize the project</label>
</div>
</li>
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo2" type="checkbox">
<label for="todo2">Create the main structure</label>
</div>
</li>
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo3" type="checkbox">
<label for="todo3">Updates changes to GitHub</label>
</div>
</li>
</ul><span class="category-title">Tomorrow</span>
<ul class="todo-list">
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo4" type="checkbox">
<label for="todo4">Initialize the project</label>
</div>
</li>
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo5" type="checkbox">
<label for="todo5">Create the main structure</label>
</div>
</li>
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo6" type="checkbox">
<label for="todo6">Updates changes to GitHub</label>
</div>
</li>
<li>
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
<input id="todo7" type="checkbox">
<label for="todo7" title="This task is too long to be displayed in a normal space!">This task is too long to be displayed in a normal space!</label>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="bottom-input">
<input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
</div>
</div>
</div>
<div id="tab3" role="tabpanel" class="tab-pane tab-settings">
<div class="settings-wrapper">
<div class="be-scroller"><span class="category-title">General</span>
<ul class="settings-list">
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" checked="" name="st1" id="st1"><span>
<label for="st1"></label></span>
</div><span class="name">Available</span>
</li>
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" checked="" name="st2" id="st2"><span>
<label for="st2"></label></span>
</div><span class="name">Enable notifications</span>
</li>
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" checked="" name="st3" id="st3"><span>
<label for="st3"></label></span>
</div><span class="name">Login with Facebook</span>
</li>
</ul><span class="category-title">Notifications</span>
<ul class="settings-list">
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" name="st4" id="st4"><span>
<label for="st4"></label></span>
</div><span class="name">Email notifications</span>
</li>
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" checked="" name="st5" id="st5"><span>
<label for="st5"></label></span>
</div><span class="name">Project updates</span>
</li>
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" checked="" name="st6" id="st6"><span>
<label for="st6"></label></span>
</div><span class="name">New comments</span>
</li>
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" name="st7" id="st7"><span>
<label for="st7"></label></span>
</div><span class="name">Chat messages</span>
</li>
</ul><span class="category-title">Workflow</span>
<ul class="settings-list">
<li>
<div class="switch-button switch-button-sm">
<input type="checkbox" name="st8" id="st8"><span>
<label for="st8"></label></span>
</div><span class="name">Deploy on commit</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
</div>
<script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
<script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
<script src="assets/js/main.js" type="text/javascript"></script>
<script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
<script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
<script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
<script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
//initialize the javascript
App.init();
App.dataTables();
$.ajax({
type:"get",
url:"http://127.0.0.1:8080/middlewareApi/",
success: function(data){
console.log(data);
$("#table-data").html("");
$.each(data['route_info'],function (i,item) {
$("#table-data").append(' <tr class="gradeA">\
<td>'+item.id+'</td>\
<td>'+item.route_name+'</td>\
<td>'+item.route_namespace+'</td>\
<td class="center">'+item.route_host+'</td>\
<td class="center"><a href="route-detail.html?route_id='+item.id+'">详情</a> <a href="http://localhost:8080/routeApi/deleteRouteById?route_id='+item.id+'" style="color:red;" >删除</a></td>\
</tr>'
);
})
},
error: function(result){
console.log(result);
}
});
});
</script>
</body>
</html>
file:///home/gopath/src/gopaas/go-paas-front/middleware-create-mysql.html
10-19 中间件前端页面以及核心API开发(下)
C:\Users\Administrator\Desktop\gopaas\middlewareapi\handler\middlewareApiHandler.go
package handler
import (
"context"
"encoding/json"
"errors"
"strconv"
log "github.com/asim/go-micro/v3/logger"
"ithub.com/yunixiangfeng/gopaas/middlewareApi/plugin/form"
"github.com/yunixiangfeng/gopaas/common"
middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)
type MiddlewareApi struct {
MiddlewareService middleware.MiddlewareService
}
// middlewareApi.FindMiddlewareById 通过API向外暴露为/middlewareApi/findMiddlewareById,接收http请求
// 即:/middlewareApi/FindMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) FindMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.FindMiddlewareById request")
if _, ok := req.Get["middle_id"]; !ok {
return errors.New("参数异常!")
}
idString := req.Get["middle_id"].Values[0]
id, err := strconv.ParseInt(idString, 10, 64)
if err != nil {
common.Error(err)
return err
}
middleInfo, err := e.MiddlewareService.FindMiddlewareByID(ctx, &middleware.MiddlewareId{Id: id})
rsp.StatusCode = 200
b, _ := json.Marshal(middleInfo)
rsp.Body = string(b)
return nil
}
// middlewareApi.AddMiddleware 通过API向外暴露为/middlewareApi/AddMiddleware,接收http请求
// 即:/middlewareApi/AddMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.AddMiddleware 方法
func (e *MiddlewareApi) AddMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.AddMiddleware request")
addMiddleInfo := &middleware.MiddlewareInfo{}
//设置端口
port, err := e.setMiddlePort(req)
if err != nil {
common.Error(err)
return err
}
addMiddleInfo.MiddlePort = port
//设置环境变量
addMiddleInfo.MiddleEnv = e.setMiddleEnv(req)
//设置存储
addMiddleInfo.MiddleStorage = e.setMiddleStorage(req)
//获取类型
middleTypeInfo := e.getMiddleType(req)
//判断不同的类型设置不同的值
switch middleTypeInfo.MiddleTypeName {
case "MYSQL":
middleConfig := e.setMiddleConfig(req)
addMiddleInfo.MiddleConfig = &middleConfig
}
//处理表单
form.FormToMiddlewareStruct(req.Post, addMiddleInfo)
//调用后端服务添加数据
response, err := e.MiddlewareService.AddMiddleware(ctx, addMiddleInfo)
if err != nil {
common.Error(err)
return err
}
rsp.StatusCode = 200
b, _ := json.Marshal(response)
rsp.Body = string(b)
return nil
}
//设置mysql config 设置
func (e *MiddlewareApi) setMiddleConfig(req *middlewareApi.Request) (middleConfig middleware.MiddleConfig) {
middleConfig.MiddleConfigRootUser = e.getValue(req, "middle_config_root_user")
middleConfig.MiddleConfigRootPwd = e.getValue(req, "middle_config_root_pwd")
middleConfig.MiddleConfigUser = e.getValue(req, "middle_config_user")
middleConfig.MiddleConfigPwd = e.getValue(req, "middle_config_pwd")
middleConfig.MiddleConfigDataBase = e.getValue(req, "middle_config_data_base")
return
}
//获取post值
func (e *MiddlewareApi) getValue(req *middlewareApi.Request, key string) string {
value, ok := req.Post[key]
if ok {
return value.Values[0]
}
return ""
}
//获取类型
func (e *MiddlewareApi) getMiddleType(req *middlewareApi.Request) (middleTypeInfo middleware.MiddleTypeInfo) {
typeValue, ok := req.Post["middle_type_id"]
if ok {
typeId, err := strconv.ParseInt(typeValue.Values[0], 10, 64)
if err != nil {
common.Error(err)
return
}
typeInfo, err := e.MiddlewareService.FindMiddleTypeByID(context.TODO(), &middleware.MiddleTypeId{
Id: typeId,
})
if err != nil {
common.Error(err)
return
}
middleTypeInfo = *typeInfo
}
return
}
//设置中间件的存储
func (e *MiddlewareApi) setMiddleStorage(req *middlewareApi.Request) []*middleware.MiddleStorage {
storageSlice := []*middleware.MiddleStorage{}
//处理环境变量
i := 1
for {
nameTag := "middle_storage.name." + strconv.Itoa(i)
sizeTag := "middle_storage.size." + strconv.Itoa(i)
pathTag := "middle_storage.path." + strconv.Itoa(i)
key, ok := req.Post[nameTag]
if ok {
sizeValue, _ := strconv.ParseFloat(req.Post[sizeTag].Values[0], 32)
storage := &middleware.MiddleStorage{
MiddleStorageName: key.Values[0],
MiddleStorageSize: float32(sizeValue),
MiddleStoragePath: req.Post[pathTag].Values[0],
MiddleStorageClass: "csi-rbd-sc",
MiddleStorageAccessMode: "ReadWriteOnce",
}
storageSlice = append(storageSlice, storage)
} else {
break
}
i++
}
return storageSlice
}
//设置中间件环境变量
func (e *MiddlewareApi) setMiddleEnv(req *middlewareApi.Request) []*middleware.MiddleEnv {
envSlice := []*middleware.MiddleEnv{}
//处理环境变量
i := 1
for {
tag := "middle_env.key." + strconv.Itoa(i)
valueTag := "middle_env.value." + strconv.Itoa(i)
key, ok := req.Post[tag]
if ok {
env := &middleware.MiddleEnv{
EnvKey: key.Values[0],
EnvValue: req.Post[valueTag].Values[0],
}
envSlice = append(envSlice, env)
} else {
break
}
i++
}
return envSlice
}
//设置端口
func (e *MiddlewareApi) setMiddlePort(req *middlewareApi.Request) ([]*middleware.MiddlePort, error) {
dataSlice, ok := req.Post["middle_port"]
if ok {
//特殊处理
middlePortSlice := []*middleware.MiddlePort{}
for _, v := range dataSlice.Values {
i, err := strconv.ParseInt(v, 10, 64)
if err != nil {
common.Error(err)
}
port := &middleware.MiddlePort{
MiddlePort: int32(i),
MiddleProtocol: "TCP",
}
middlePortSlice = append(middlePortSlice, port)
}
return middlePortSlice, nil
}
return nil, errors.New("无端口")
}
// middlewareApi.DeleteMiddlewareById 通过API向外暴露为/middlewareApi/DeleteMiddlewareById,接收http请求
// 即:/middlewareApi/DeleteMiddlewareById 请求会调用go.micro.api.middlewareApi 服务的 middlewareApi.DeleteMiddlewareById 方法
func (e *MiddlewareApi) DeleteMiddlewareById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.DeleteMiddlewareById request")
if _, ok := req.Get["middle_id"]; !ok {
return errors.New("参数异常")
}
IdString := req.Get["middle_id"].Values[0]
Id, err := strconv.ParseInt(IdString, 10, 64)
if err != nil {
common.Error(err)
return err
}
response, err := e.MiddlewareService.DeleteMiddleware(ctx, &middleware.MiddlewareId{
Id: Id,
})
rsp.StatusCode = 200
b, _ := json.Marshal(response)
rsp.Body = string(b)
return nil
}
// middlewareApi.UpdateMiddleware 通过API向外暴露为/middlewareApi/UpdateMiddleware,接收http请求
// 即:/middlewareApi/UpdateMiddleware 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.UpdateMiddleware 方法
func (e *MiddlewareApi) UpdateMiddleware(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.UpdateMiddleware request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问/middlewareApi/UpdateMiddleware'}")
rsp.Body = string(b)
return nil
}
// 默认的方法middlewareApi.Call 通过API向外暴露为/middlewareApi/call,接收http请求
// 即:/middlewareApi/call或/middlewareApi/ 请求会调用go.micro.api.middlewareApi 服务的middlewareApi.FindMiddlewareById 方法
func (e *MiddlewareApi) Call(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问:Call'}")
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) FindAllMiddlewareByTypeId(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问:Call'}")
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) FindMiddleTypeById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问:Call'}")
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) AddMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
typeInfo := &middleware.MiddleTypeInfo{
//MiddleTypeName: "CONSUL",
//MiddleTypeImageSrc: "/consul.jpg",
//MiddleVersion: []*middleware.MiddleVersion{
// {
// MiddleDockerImage: "docker/consul",
// MiddleVs: "v1.0.1",
// },
// {
// MiddleDockerImage: "docker/consul",
// MiddleVs: "v1.0.2",
// },
//},
}
rspInfo, err := e.MiddlewareService.AddMiddleType(ctx, typeInfo)
if err != nil {
common.Error(err)
return err
}
rsp.StatusCode = 200
b, _ := json.Marshal(rspInfo)
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) DeleteMiddleTypeById(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问:Call'}")
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) UpdateMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
rsp.StatusCode = 200
b, _ := json.Marshal("{success:'成功访问:Call'}")
rsp.Body = string(b)
return nil
}
func (e *MiddlewareApi) FindAllMiddleType(ctx context.Context, req *middlewareApi.Request, rsp *middlewareApi.Response) error {
log.Info("Received middlewareApi.Call request")
allType, err := e.MiddlewareService.FindAllMiddleType(ctx, &middleware.FindAll{})
if err != nil {
common.Error(err)
return err
}
rsp.StatusCode = 200
b, _ := json.Marshal(allType)
rsp.Body = string(b)
return nil
}
C:\Users\Administrator\Desktop\gopaas\middlewareapi\plugin\form\form.go
package form
import (
"errors"
"strings"
"reflect"
"strconv"
"time"
"github.com/yunixiangfeng/gopaas/common"
"github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)
//根据结构体中name标签映射数据到结构体中并且转换类型
func FormToMiddlewareStruct(data map[string]*middlewareApi.Pair, obj interface{}) {
objValue := reflect.ValueOf(obj).Elem()
for i := 0; i < objValue.NumField(); i++ {
//获取sql对应的值
dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
dataSlice, ok := data[dataTag]
if !ok {
continue
}
valueSlice := dataSlice.Values
if len(valueSlice) <= 0 {
continue
}
//排除port和env
if dataTag == "middle_port" {
continue
}
value := valueSlice[0]
//端口,环境变量的单独处理
//获取对应字段的名称
name := objValue.Type().Field(i).Name
//特殊类型跳过单独处理
if name == "MiddleStorage" {
continue
}
//获取对应字段类型
structFieldType := objValue.Field(i).Type()
//获取变量类型,也可以直接写"string类型"
val := reflect.ValueOf(value)
var err error
if structFieldType != val.Type() {
//类型转换
val, err = TypeConversion(value, structFieldType.Name()) //类型转换
if err != nil {
common.Error(err)
}
}
//设置类型值
objValue.FieldByName(name).Set(val)
}
}
//类型转换
func TypeConversion(value string, ntype string) (reflect.Value, error) {
if ntype == "string" {
return reflect.ValueOf(value), nil
} else if ntype == "time.Time" {
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
return reflect.ValueOf(t), err
} else if ntype == "Time" {
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
return reflect.ValueOf(t), err
} else if ntype == "int" {
i, err := strconv.Atoi(value)
return reflect.ValueOf(i), err
} else if ntype == "int32" {
i, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return reflect.ValueOf(int32(i)), err
}
return reflect.ValueOf(int32(i)), err
} else if ntype == "int64" {
i, err := strconv.ParseInt(value, 10, 64)
return reflect.ValueOf(i), err
} else if ntype == "float32" {
i, err := strconv.ParseFloat(value, 64)
return reflect.ValueOf(float32(i)), err
} else if ntype == "float64" {
i, err := strconv.ParseFloat(value, 64)
return reflect.ValueOf(i), err
}
//else if .......增加其他一些类型的转换
return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
}
C:\Users\Administrator\Desktop\gopaas\middlewareapi\main.go
package main
import (
"fmt"
"github.com/afex/hystrix-go/hystrix"
"github.com/asim/go-micro/plugins/registry/consul/v3"
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
"github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
"github.com/asim/go-micro/v3"
"github.com/asim/go-micro/v3/registry"
"github.com/asim/go-micro/v3/server"
"github.com/yunixiangfeng/gopaas/common"
go_micro_service_middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
"net"
"net/http"
"strconv"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/opentracing/opentracing-go"
"github.com/yunixiangfeng/gopaas/middlewareApi/handler"
hystrix2 "github.com/yunixiangfeng/gopaas/middlewareApi/plugin/hystrix"
middlewareApi "github.com/yunixiangfeng/gopaas/middlewareApi/proto/middlewareApi"
)
var (
//服务地址
hostIp = "192.168.204.130"
//服务地址
serviceHost = hostIp
//服务端口
servicePort = "8090"
//注册中心配置
consulHost = hostIp
consulPort int64 = 8500
//链路追踪
tracerHost = hostIp
tracerPort = 6831
//熔断端口,每个服务不能重复
hystrixPort = 9100
//监控端口,每个服务不能重复
prometheusPort = 9200
)
func main() {
//需要本地启动,mysql,consul中间件服务
//1.注册中心
consul := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{
consulHost + ":" + strconv.FormatInt(consulPort, 10),
}
})
//2.添加链路追踪
t, io, err := common.NewTracer("go.micro.api.middlewareApi", tracerHost+":"+strconv.Itoa(tracerPort))
if err != nil {
common.Error(err)
}
defer io.Close()
opentracing.SetGlobalTracer(t)
//3.添加熔断器
hystrixStreamHandler := hystrix.NewStreamHandler()
hystrixStreamHandler.Start()
//添加日志中心
//1)需要程序日志打入到日志文件中
//2)在程序中添加filebeat.yml 文件
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
//启动监听程序
go func() {
//http://192.168.204.130:9092/turbine/turbine.stream
//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
if err != nil {
common.Error(err)
}
}()
//4.添加监控
common.PrometheusBoot(prometheusPort)
//5.创建服务
service := micro.NewService(
//自定义服务地址,且必须写在其它参数前面
micro.Server(server.NewServer(func(opts *server.Options) {
opts.Advertise = serviceHost + ":" + servicePort
})),
micro.Name("go.micro.api.middlewareApi"),
micro.Version("latest"),
//指定服务端口
micro.Address(":"+servicePort),
//添加注册中心
micro.Registry(consul),
//添加链路追踪
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
//只作为客户端的时候起作用
micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
//添加限流
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
//增加负载均衡
micro.WrapClient(roundrobin.NewClientWrapper()),
)
service.Init()
// 指定需要访问的服务,可以快速操作已开发的服务,
// 默认API服务名称带有"Api",程序会自动替换
// 如果不带有特定字符会使用默认"XXX" 请自行替换
middlewareService := go_micro_service_middleware.NewMiddlewareService("go.micro.service.middleware", service.Client())
// 注册控制器
if err := middlewareApi.RegisterMiddlewareApiHandler(service.Server(), &handler.MiddlewareApi{MiddlewareService: middlewareService}); err != nil {
common.Error(err)
}
// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}
10-20 总结&思考
GO PaaS 平台中间件创建与管理
主要内容
中间件服务端开发
中间件服务API开放
中间件页面联调
中间件为什么挂载盘会创建多个?
中间件集群模式如何搞定?
10-21 【扩展阅读】k8s 实战篇 – Mysql 容器化部署详解
第11章 云原生 Go PaaS 平台镜功能开发,商业化镜像市场,完善平台市场功能
开发完成的应用能够包装成各自独立的应用程序,以便于在市场上通过售卖和安装的方式给客户获取到。开发满足业务需求的镜像市场功能,使得我们的应用能够像APP 应用一样在 PaaS 平台上购买和被安装。
11-1 云应用市场开发介绍
11-2 云应用app_store模型开发及管理说明
11-3 云应用辅助信息model 开发
11-4 云应用市场 repository 代码开发
11-5 云应用平台Service 代码开发
11-6 云应用市场服务端Proto 开发
11-7 云应用市场服务端 handler 开发
11-8 云应用市场APi Proto 开发
11-9 云应用市场 API form 表单处理研发
11-10 云应用添加应用addAppStore 接口(上)
11-11 云应用addAppStore(中)
11-12 云应用市场API 开发(下)
11-13 总结&思考
第12章 云原生GoPaaS平台用户中心,健全验证统一管理
系统规模愈来愈大,人员规模成倍增长,关联的人员需要有精确的权限控制体系。本章通过权限管理,提供PaaS 平台的权限服务,得每个操作都可以进行权限控制,达到精细化管理PaaS 平台的目的。