paulwong

#

KEYCLOAK授权模式与实施


https://stackoverflow.com/questions/42186537/resources-scopes-permissions-and-policies-in-keycloak

posted @ 2022-04-21 15:32 paulwong 阅读(152) | 评论 (0)编辑 收藏

KEYCLOA+DMariaDB 在LINUX上的安装

下载KEYCLOAK与安装,可参见:
https://www.janua.fr/how-to-install-keycloak-with-mariadb/

启动时配置不通过localhost访问控制台:
#! /bin/bash

BIN_PATH=$(cd `dirname $0`; pwd)
IP=10.10.27.69
KEYCLOAK_OPT="-b ${IP} -Djboss.bind.address.management=${IP} -Dkeycloak.profile.feature.upload_scripts=enabled"
KEYCLOAK_OPT="${KEYCLOAK_OPT} -Djboss.socket.binding.port-offset=100 -Dkeycloak.frontendUrl=http://${IP}:81/auth "
#-Dkeycloak.hostname=${IP} -Dkeycloak.httpPort=81 -Dkeycloak.httpsPort=82

nohup ${BIN_PATH}/bin/standalone.sh ${KEYCLOAK_OPT} > /dev/null &

更改KEYCLOAK的DATASOURCE时,可直接更改默认的而无需重新配置:
https://medium.com/@pratik.dandavate/setting-up-keycloak-standalone-with-mysql-database-7ebb614cc229

KEYCLOAK的JBOSS管理界面地址改为非LOCALHOST:
-Djboss.bind.address.management=${IP}

如果是由NGINX过来的访问,这样前端的地址是和默认的不一样,需配置前端URL:
-Dkeycloak.frontendUrl=http://${IP}:81/auth

更改JVM大小standalone.conf:
#
# Specify options to pass to the Java VM.
#

JBOSS_JAVA_SIZING="-server -Xms3G -Xmx3G -Xmn512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m"

REFERENCE:
https://www.keycloak.org/docs/latest/server_installation/index.html#_hostname

posted @ 2022-04-14 15:15 paulwong 阅读(225) | 评论 (0)编辑 收藏

UML DIAGRAM资源

https://www.uml-diagrams.org/uml-25-diagrams.html


https://www.uml-diagrams.org/index-examples.html

posted @ 2022-02-19 16:55 paulwong 阅读(115) | 评论 (0)编辑 收藏

JENKINS 部署 agularjs

This article assumes that you have a running Jenkins instance on your Linux machine with a valid domain (not localhost), GitLab and that you are familiar with the Angular framework.

For Jenkins, please install the GitLab and NodeJS plugins. For simplicity’s sake, this article is going to use simple shell commands to run automated tests and to deploy an app to production.

***Note. If you can’t decide where to test all this, there is an article I wrote that might help you: CI/CD Cloud Voyage with Jenkins.

Configuring Gitlab and Jenkins

Jenkins: Access Rights to GitLab

In order to use GitLab with Jenkins, you’ll need to generate an access token in GitLab, which you can do in User menu > Settings > Access tokens

and configure GitLab Connection on Jenkins by adding the newly generated token.

In Jenkins, go to Manage Jenkins > Configure system and find the GitLab section.

To add a token that you previously generated, click on Add by the Credentials input and choose Jenkins. In the credentials dialog, choose GitLab API token in the Kind input and paste your token from GitLab into the API token input field. 

Jenkins: Configure NodeJSInstaller

In order to be able to run npm scripts, it is necessary to configure NodeJSInstaller. In Jenkins, go to Manage Jenkins > Global Tool Configuration > NodeJS installations.

Jenkins: Create CI build for Angular

In order to be able to run Angular tests and check your code style in Jenkins on the created merge request in GitLab you’ll have to:

1. Click on the New item link in the Jenkins dashboard

2. Enter a job name and choose Freestyle project

3. Choose the GitLab Connection that we’ve just created in the Gitlab Connection section.

4. Choose Git as your source code management. Enter your repository URL. Create new credentials on Jenkins. These credentials are for cloning the project. You use them to log in to Gitlab.

5. Next, configure build triggers, i.e. on which GitLab event to run a build. In this particular example, angular-ci-build is going to trigger when a new merge request gets created.

In this step, we need to go back to GitLab and create a hook that will trigger this build under Settings > Integrations. Copy the URL provided by Jenkins and paste it into the project hook form and finally click Add webhook.

6. Provide the configured NodeJsInstaller in the global configuration to be able to run npm commands.

7. And finally, in the Build section choose Add build step > Execute shell. Write shell scripts to test the Angular app code and run tests.

Click Save and we are good to go. At this point everything should work.

When you create a new merge request, GitLab should trigger angular-ci-build on Jenkins and you should see status pending on that particular merge request page.

When Jenkins is done, the status on GitLab should automatically be updated. Depending on whether the build passed or not, the merge button will change color.

Jenkins: Create CD Build for Angular

In order to be able to deploy Angular to another Linux machine, we need to:

Repeat steps 1–4 from Jenkins: Create CI Build for Angular, changing only the name of the build. This time, it can be angular-deploy. 

5. For step five, we now choose a different configuration for deployment. We are going to run this build when a merge request gets accepted.

Just like for the CI build, we have to create a new GitLab hook that will hit the Jenkins build endpoint.

6. This step is also the same as in CI; we need to provide the NodeJSInstaller we already configured globally.

7. This step is different from CI; this time we don’t have to test and check linting, but only build the application and copy-paste it to another machine with ssh.

If we are going to do it with ssh like in the example, we need to create a private and public key pair for the Jenkins user on the machine Jenkins is running on. The private key needs to stay on the Jenkins machine, and the public key needs to be copied to the remote machine.

With the scp command we simply copy our build to the remote machine. In this case, Jenkins does not have permission to put it anywhere but in the user folder. In the last step, we need to ssh into the remote machine and move our files (in this case to /var/www/html).

Voila, our app is deployed to the production server when the merge request is accepted via Jenkins.

Angular: Karma Unit Test Runner Configuration

To run Angular tests on Jenkins, we need to configure some parts of the karma.conf file. Below is the configuration that adds a custom launcher that runs ChromeHeadles.

module.exports = function(config) {   config.set({     basePath: "",     frameworks: ["jasmine", "@angular-devkit/build-angular"],     plugins: [       require("karma-jasmine"),       require("karma-chrome-launcher"),       require("karma-jasmine-html-reporter"),       require("karma-coverage-istanbul-reporter"),       require("@angular-devkit/build-angular/plugins/karma")     ],     client: {       clearContext: false // leave Jasmine Spec Runner output visible in browser     },     coverageIstanbulReporter: {       dir: require("path").join(__dirname, "../coverage/jenkins-test-app"),       reports: ["html", "lcovonly", "text-summary"],       fixWebpackSourcePaths: true     },     reporters: ["progress", "kjhtml"],     port: 9876,     colors: true,     logLevel: config.LOG_INFO,     autoWatch: true,     browsers: ["Chrome", "ChromeHeadless"],     singleRun: false,     restartOnFileChange: true,     customLaunchers: {       ChromeHeadless: {         base: "Chrome",         flags: [           "--headless",           "--disable-gpu",           "--no-sandbox",           "--remote-debugging-port=9222"         ],                },     }   }); };

We can then simply store our command in the package.json scripts property.

On Jenkins, we would now run our tests with npm run test:ci.

 "scripts": {     "ng": "ng",     "start": "ng serve",     "build": "ng build",     "test": "ng test",     "test:ci": "ng test --browsers=ChromeHeadless --watch=false",     "lint": "ng lint",     "e2e": "ng e2e"   },

I hope you enjoyed this article and that it was helpful in your quest for automating angular deployment and testing.

posted @ 2022-01-25 11:02 paulwong 阅读(136) | 评论 (0)编辑 收藏

SPRING INTEGRATION - 集群选主、分布式锁

集群通常是有多个相同的实例,但对于定时任务场景,只希望有一个实例工作即可,如果这个实例挂了,其他实例可以顶替。

这个问题的方案则是集群选主,一个集群中,只有一个LEADER,由LEADER负责执行定时任务工作。当LEADER被取消时,会在剩下的实例中再选LEADER。

持有分布式锁的实例则是LEADER。

SPRING INTEGRATION JDBC 则已提供相关功能。

pom.xml
        <dependency>
           <groupId>org.springframework.integration</groupId>
           <artifactId>spring-integration-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
           <groupId>org.flywaydb</groupId>
           <artifactId>flyway-core</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
        </dependency>

LeaderElectionIntegrationConfig.java
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.jdbc.lock.DefaultLockRepository;
import org.springframework.integration.jdbc.lock.JdbcLockRegistry;
import org.springframework.integration.jdbc.lock.LockRepository;
import org.springframework.integration.support.leader.LockRegistryLeaderInitiator;

import com.paul.integration.leader.ControlBusGateway;
import com.paul.integration.leader.MyCandidate;

@Configuration
public class LeaderElectionIntegrationConfig {
    
    @Bean
    public List<String> needToStartupAdapterList(){
        return new CopyOnWriteArrayList<>();
    }
    
    @Bean
    public DefaultLockRepository defaultLockRepository(DataSource dataSource){
        DefaultLockRepository defaultLockRepository =
                new DefaultLockRepository(dataSource);
//        defaultLockRepository.setTimeToLive(60_000);
        return defaultLockRepository;
    }

    @Bean
    public JdbcLockRegistry jdbcLockRegistry(LockRepository lockRepository){
        return new JdbcLockRegistry(lockRepository);
    }
    
    @Bean
    public MyCandidate myCandidate(
        ControlBusGateway controlBusGateway,
        List<String> needToStartupAdapterList
    ) {
        return new MyCandidate(controlBusGateway, needToStartupAdapterList);
    }
    
    @Bean
    public LockRegistryLeaderInitiator leaderInitiator() {
        return new LockRegistryLeaderInitiator(
                    jdbcLockRegistry(null), myCandidate(nullnull)
               );
    }
    
    
}


MyCandidate.java
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.leader.Context;
import org.springframework.integration.leader.DefaultCandidate;

import com.novacredit.mcra.mcracommon.integration.gateway.ControlBusGateway;

public class MyCandidate extends DefaultCandidate{
    
    private static final Logger LOG = LoggerFactory.getLogger(MyCandidate.class);
    
    private List<String> needToStartupAdapterList;
    
    private ControlBusGateway controlBusGateway;
    
    public MyCandidate(
        ControlBusGateway controlBusGateway,
        List<String> needToStartupAdapterList
    ) {
        this.controlBusGateway = controlBusGateway;
        this.needToStartupAdapterList = needToStartupAdapterList;
    }
    
    @Override
    public void onGranted(Context context) {
        super.onGranted(context);
        LOG.info("*** Leadership granted ***");
        LOG.info("STARTING MONGODB POLLER");
        needToStartupAdapterList
            .forEach(
                c -> {
//                    c = "@'testIntegrationFlow.org.springframework.integration.config."
//                            + "SourcePollingChannelAdapterFactoryBean#0'";
                    String command = c + ".start()";
                    LOG.info("-----{}", command);
                    controlBusGateway.sendCommand(command);
                }
             );
        LOG.info("STARTUP MESSAGE SENT");

    }

    @Override
    public void onRevoked(Context context) {
        super.onRevoked(context);
        LOG.info("*** Leadership revoked ***");
        LOG.info("STOPPING MONGODB POLLER");
        needToStartupAdapterList
            .forEach(
                c -> {
//                    c = "@'testIntegrationConfig.testIntegrationFlow."
//                            + "mongoMessageSource.inboundChannelAdapter'";
                    String command = c + ".stop()";
                    LOG.info("-----{}", command);
//                    controlBusGateway.sendCommand(command);
                }
             );
        LOG.info("SHUTDOWN MESSAGE SENT");
    }

}


ControlBusIntegrationConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
import org.springframework.integration.handler.LoggingHandler;
import org.springframework.messaging.MessageChannel;

import com.paul.integration.gateway.ControlBusGateway;

@Configuration
public class ControlBusIntegrationConfig {
    
    @Bean
    public MessageChannel controlBusChannel() {
        return MessageChannels.direct().get();
    }
    
    @Bean
    public IntegrationFlow controlBusFlow() {
        return IntegrationFlows.from(controlBusChannel())
                    .log(LoggingHandler.Level.INFO, "controlBusChannel")
                    .controlBus()
                    .get();
    }
    
    @Bean
    public GatewayProxyFactoryBean controlBusGateway() {
        GatewayProxyFactoryBean gateway = new GatewayProxyFactoryBean(ControlBusGateway.class);
        gateway.setDefaultRequestChannel(controlBusChannel());
        gateway.setDefaultRequestTimeout(300l);
        gateway.setDefaultReplyTimeout(300l);
        return gateway;
    }
    
}


ControlBusGateway.java
public interface ControlBusGateway {
    
    public void sendCommand(String command);

}


各个应用实例运行时,其中的LockRegistryLeaderInitiator会自动运行,抢夺LEADER数据,最终只有一个实例夺取。之后再执行MyCandidate中的代码。







posted @ 2022-01-20 13:49 paulwong 阅读(517) | 评论 (0)编辑 收藏

MONGODB SHELL

mongo -u admin -p 123456 --authenticationDatabase admin
use admin
db.createUser({
 user : "paul",
 pwd : "123456",
 roles : [{role : "readWrite", db : "batch"}]
})

#增加权限
db.grantRolesToUser( 
  "paul"
  [
    { "role" : "dbOwner",
      "db" : "mcra"
    }
  ]
)

posted @ 2022-01-10 11:10 paulwong 阅读(220) | 评论 (0)编辑 收藏

OAUTH2 - 4流程如何选择?





https://developer.okta.com/docs/concepts/oauth-openid/#what-kind-of-client-are-you-building

posted @ 2022-01-06 13:37 paulwong 阅读(136) | 评论 (0)编辑 收藏

几个好看的免费UI

https://demos.creative-tim.com/light-bootstrap-dashboard-angular2/#/dashboard


https://www.creative-tim.com/product/light-bootstrap-dashboard-angular2

https://www.creative-tim.com/templates/angular-dashboard-bootstrap

https://coreui.io/angular/demo/free/2.11.1/#/base/tables

posted @ 2022-01-04 15:36 paulwong 阅读(178) | 评论 (0)编辑 收藏

Easily Secure your Microservices with Keycloak

https://www.doag.org/formes/pubfiles/11143470/2019-NN-Sebastien_Blanc-Easily_Secure_your_Microservices_with_Keycloak-Praesentation.pdf

posted @ 2022-01-03 10:03 paulwong 阅读(141) | 评论 (0)编辑 收藏

REDHEAD 7 LINUX 软件集合

https://www.softwarecollections.org/en/

不用再GOOGLE寻找安装方法。

安装MYSQL示例:
# 2. Install the collection:
$ sudo yum install rh-mariadb103

# 3. Start using software collections:
$ scl enable rh-mariadb103 bash

$ service rh-mariadb103-mariadb start 
$ mysql
$ mysqld

#开机加载命令
cp /opt/rh/rh-mariadb103/enable /etc/profile.d/rh-mariadb103.sh

posted @ 2021-12-22 14:28 paulwong 阅读(194) | 评论 (0)编辑 收藏

仅列出标题
共112页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last