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 平台的目的。


















