work on using admin application as kie-server rest interface to allow deploy action from within Business Central

This commit is contained in:
Nicolas Héron 2020-07-01 11:23:20 +02:00
commit f97a3889a5
9 changed files with 566 additions and 10 deletions

View file

@ -14,23 +14,31 @@ import org.chtijbug.drools.common.KafkaTopicConstants;
import org.chtijbug.drools.console.middle.DababaseContentInit;
import org.chtijbug.drools.console.service.model.kie.KieConfigurationData;
import org.chtijbug.drools.console.service.util.ApplicationContextProvider;
import org.chtijbug.drools.console.service.wbconnector.KieBusinessCentralConnector;
import org.chtijbug.drools.proxy.persistence.model.ProjectPersist;
import org.chtijbug.drools.proxy.persistence.repository.ProjectRepository;
import org.kie.server.api.model.KieContainerResource;
import org.kie.server.controller.api.model.KieServerSetup;
import org.kie.server.controller.api.model.runtime.ServerInstanceKey;
import org.kie.server.controller.api.model.runtime.ServerInstanceKeyList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.EventListener;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.kafka.annotation.EnableKafka;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.support.serializer.JsonDeserializer;
import org.springframework.kafka.support.serializer.JsonSerializer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.HashMap;
import java.util.Map;
@ -50,6 +58,28 @@ public class DroolsSpringBootConsoleApplication extends SpringBootServletInitial
@Autowired
private DababaseContentInit dababaseContentInit;
@Autowired
private KieBusinessCentralConnector kieBusinessCentralConnector;
@Autowired
private ProjectRepository projectRepository;
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "OPTIONS", "DELETE", "PUT")
.allowedHeaders("Access-Control-Allow-Origin", "*")
.exposedHeaders("Access-Token", "Access-Control-Allow-Origin")
.allowCredentials(false).maxAge(3600);
}
};
}
@Bean(name = "applicationContext")
public ApplicationContextProvider getAppplicationContext() {
@ -142,9 +172,35 @@ public class DroolsSpringBootConsoleApplication extends SpringBootServletInitial
SpringApplication.run(DroolsSpringBootConsoleApplication.class, args);
}
@EventListener(ApplicationReadyEvent.class)
// @EventListener(ApplicationReadyEvent.class)
public void InitPlatform(){
dababaseContentInit.initDatabaseIfNecessary();
Map<String,KieContainerResource> kies = new HashMap<>();
KieServerSetup kieServerSetup = kieBusinessCentralConnector.connectToBusinessCentral("nheron", "adminnheron00@");
if (kieServerSetup!= null && kieServerSetup.getContainers()!= null) {
for (KieContainerResource kieContainerResource : kieServerSetup.getContainers()) {
kies.put(kieContainerResource.getContainerId(), kieContainerResource);
}
}
for (ProjectPersist projectPersist : projectRepository.findAll()){
if (projectPersist.getServerNames().size()>0){
if (!kies.containsKey(projectPersist.getContainerID())){
kieBusinessCentralConnector.createContainer("nheron", "adminnheron00@",projectPersist);
}else{
kieBusinessCentralConnector.updateContainer("nheron", "adminnheron00@",projectPersist,kies.get(projectPersist.getContainerID()));
}
}
}
ServerInstanceKeyList serverInstanceKeyList = kieBusinessCentralConnector.getListInstances("nheron", "adminnheron00@");
if (serverInstanceKeyList!=null){
for (ServerInstanceKey serverInstanceKey : serverInstanceKeyList.getServerInstanceKeys()){
//serverInstanceKey.get
}
System.out.println("coucou");
}
System.out.println("coucou");
}

View file

@ -0,0 +1,38 @@
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.chtijbug.drools.console.service.kieserver;
import org.kie.server.api.commands.CommandScript;
import org.springframework.web.bind.annotation.*;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@RestController
@RequestMapping("/server/config")
public class KieServerResource {
public KieServerResource() {
}
@PostMapping(consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response executeCommands(@RequestHeader HttpHeaders headers,
@RequestBody CommandScript command ) {
return null;
}
}

View file

@ -0,0 +1,184 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.chtijbug.drools.console.service.kieserver;
import org.kie.server.api.model.KieContainerResourceFilter;
import org.kie.server.api.model.KieContainerStatusFilter;
import org.kie.server.api.model.KieServerInfo;
import org.kie.server.api.model.ReleaseIdFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import static org.kie.server.api.rest.RestURI.CONTAINER_ID;
@RestController
@RequestMapping("/server")
public class KieServerRestImpl {
@Value(value = "${org.kie.server.id}")
private String kieserverID;
@Value("${org.kie.server.controller}")
private String kiewbUrl;
@Value("${org.kie.server.location}")
private String controlerLocation;
public KieServerRestImpl() {
// for now, if no server impl is passed as parameter, create one
}
//@RequestHeader HttpHeaders headers
@GetMapping(produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public KieServerInfo getInfo() {
KieServerInfo kieServerInfo = new KieServerInfo();
kieServerInfo.setServerId(kieserverID);
kieServerInfo.setLocation(controlerLocation);
kieServerInfo.setName(kieserverID);
kieServerInfo.setCapabilities(new ArrayList<>());
kieServerInfo.getCapabilities().add("BRM");
return kieServerInfo;
}
@GetMapping(path = "/containers",
produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response listContainers(@RequestHeader HttpHeaders headers,
@RequestParam("groupId") String groupId,
@RequestParam("artifactId") String artifactId,
@RequestParam("version") String version,
@RequestParam("status") String status) {
ReleaseIdFilter releaseIdFilter = new ReleaseIdFilter.Builder()
.groupId(groupId)
.artifactId(artifactId)
.version(version)
.build();
KieContainerStatusFilter statusFilter = KieContainerStatusFilter.parseFromNullableString(status);
KieContainerResourceFilter containerFilter = new KieContainerResourceFilter(releaseIdFilter, statusFilter);
return null;
}
@PutMapping(path = "/containers/{" + CONTAINER_ID + "}",
consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response createContainer(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id,
String containerPayload) {
return null;
}
@PutMapping(path = "/containers/{" + CONTAINER_ID + "}/status/activated",
consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response activateContainer(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@PutMapping(path="/containers/{" + CONTAINER_ID + "}/status/deactivated",
consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response deactivateContainer(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@GetMapping(path="/containers/{" + CONTAINER_ID + "}",
consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getContainerInfo(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@DeleteMapping(path="/containers/{" + CONTAINER_ID + "}",
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response disposeContainer(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@GetMapping(path="/containers/{" + CONTAINER_ID + "}/scanner",
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getScannerInfo(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@PostMapping(path="/containers/{" + CONTAINER_ID + "}/scanner",
consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response updateScanner(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id,
String resourcePayload) {
return null;
}
@GetMapping(path="/containers/{" + CONTAINER_ID + "}/release-id",
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getReleaseId(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id) {
return null;
}
@PostMapping(path="/containers/{" + CONTAINER_ID + "}/release-id",
consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML},
produces={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response updateReleaseId(@RequestHeader HttpHeaders headers,
@PathVariable(CONTAINER_ID) String id,
String releaseIdPayload,
@RequestParam(value = "resetBeforeUpdate", defaultValue = "false") boolean resetBeforeUpdate) {
return null;
}
@GetMapping(path="/state",consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getServerState(@RequestHeader HttpHeaders headers) {
return null;
}
@GetMapping(path="/readycheck",consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response readycheck(@RequestHeader HttpHeaders headers) {
return null;
}
@GetMapping(path="/healthcheck",consumes={MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response healthcheck(@RequestHeader HttpHeaders headers,
@RequestParam(value = "report", defaultValue = "false") boolean report) {
return null;
}
}

View file

@ -0,0 +1,212 @@
package org.chtijbug.drools.console.service.wbconnector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.apache.commons.codec.binary.Base64;
import org.chtijbug.drools.proxy.persistence.model.ProjectPersist;
import org.kie.server.api.model.*;
import org.kie.server.controller.api.model.KieServerSetup;
import org.kie.server.controller.api.model.runtime.ServerInstanceKeyList;
import org.kie.server.controller.api.model.spec.ContainerSpec;
import org.kie.server.controller.api.model.spec.ServerTemplateKey;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
@Service
public class KieBusinessCentralConnector {
@Value(value = "${org.kie.server.id}")
private String kieserverID;
@Value("${org.kie.server.controller}")
private String kiewbUrl;
@Value("${org.kie.server.location}")
private String controlerLocation;
private RestTemplate restTemplateKiewb ;
private ObjectMapper mapper = new ObjectMapper();
public KieBusinessCentralConnector() {
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
restTemplateKiewb= new RestTemplate(factory);
restTemplateKiewb.setInterceptors(Collections.singletonList(new LoggingRequestResponseLoggingInterceptor()));
mapper.registerModule(new JaxbAnnotationModule());
}
public String createContainer(String username, String password, ProjectPersist projectPersist){
String completeurl=kiewbUrl+"/controller/management/servers/"+kieserverID+"/containers/"+projectPersist.getContainerID();
ContainerSpec containerSpec = new ContainerSpec();
containerSpec.setId(projectPersist.getContainerID());
containerSpec.setContainerName(projectPersist.getContainerID());
containerSpec.setReleasedId(new ReleaseId());
containerSpec.setStatus(KieContainerStatus.STARTED);
containerSpec.getReleasedId().setArtifactId(projectPersist.getArtifactID());
containerSpec.getReleasedId().setGroupId(projectPersist.getGroupID());
containerSpec.getReleasedId().setVersion(projectPersist.getProjectVersion());
ResponseEntity<String> response = restTemplateKiewb
.execute(completeurl, HttpMethod.PUT, requestCallback(containerSpec, username, password), clientHttpResponse -> {
String extractedResponse = null;
ResponseEntity<String> extractedValue=null;
if (clientHttpResponse.getBody() != null) {
Scanner s = new Scanner(clientHttpResponse.getBody()).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
if (result==null || result.length()==0){
}else {
extractedResponse = mapper.readValue(result, String.class);
extractedValue = new ResponseEntity<>(extractedResponse, clientHttpResponse.getHeaders(), clientHttpResponse.getStatusCode());
}
}
return extractedValue;
});
if (response!= null) {
return response.getBody();
}else {
return null;
}
}
public String updateContainer(String username, String password, ProjectPersist projectPersist, KieContainerResource kieContainerResource){
String completeurl=kiewbUrl+"/controller/management/servers/"+kieserverID+"/containers/"+projectPersist.getContainerID();
ContainerSpec containerSpec = new ContainerSpec();
containerSpec.setId(projectPersist.getContainerID());
containerSpec.setContainerName(projectPersist.getContainerID());
containerSpec.setReleasedId(new ReleaseId());
containerSpec.setStatus(KieContainerStatus.STARTED);
containerSpec.getReleasedId().setArtifactId(projectPersist.getArtifactID());
containerSpec.getReleasedId().setGroupId(projectPersist.getGroupID());
containerSpec.getReleasedId().setVersion(projectPersist.getProjectVersion());
containerSpec.setServerTemplateKey(new ServerTemplateKey());
containerSpec.getServerTemplateKey().setId(kieserverID);
containerSpec.getServerTemplateKey().setName(kieserverID);
ResponseEntity<String> response = restTemplateKiewb
.execute(completeurl, HttpMethod.POST, requestCallback(containerSpec, username, password), clientHttpResponse -> {
String extractedResponse = null;
ResponseEntity<String> extractedValue=null;
if (clientHttpResponse.getBody() != null) {
Scanner s = new Scanner(clientHttpResponse.getBody()).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
if (result==null || result.length()==0){
}else {
extractedResponse = mapper.readValue(result, String.class);
extractedValue = new ResponseEntity<>(extractedResponse, clientHttpResponse.getHeaders(), clientHttpResponse.getStatusCode());
}
}
return extractedValue;
});
if (response!= null) {
return response.getBody();
}else {
return null;
}
}
public ServerInstanceKeyList getListInstances(String username, String password){
String completeurl=kiewbUrl+"/controller/runtime/servers/"+kieserverID+"/instances";
ResponseEntity<ServerInstanceKeyList> response = restTemplateKiewb
.execute(completeurl, HttpMethod.GET, requestCallback(null, username, password), clientHttpResponse -> {
ServerInstanceKeyList extractedResponse;
ResponseEntity<ServerInstanceKeyList> extractedValue=null;
if (clientHttpResponse.getBody() != null) {
//Scanner s = new Scanner(clientHttpResponse.getBody()).useDelimiter("\\A");
//String result = s.hasNext() ? s.next() : "";
String result = StreamUtils.copyToString(clientHttpResponse.getBody(), Charset.defaultCharset());
if (result==null || result.length()==0){
}else {
extractedResponse = mapper.readValue(result, ServerInstanceKeyList.class);
extractedValue = new ResponseEntity<>(extractedResponse, clientHttpResponse.getHeaders(), clientHttpResponse.getStatusCode());
}
}
return extractedValue;
});
if (response!= null) {
return response.getBody();
}else {
return null;
}
}
public KieServerSetup connectToBusinessCentral(String username, String password){
String completeurl=kiewbUrl+"/controller/server/"+kieserverID;
KieServerInfo kieServerInfo = new KieServerInfo();
kieServerInfo.setVersion("1.0.0");
kieServerInfo.setServerId("1");
kieServerInfo.setName(kieserverID);
kieServerInfo.setMode(KieServerMode.DEVELOPMENT);
kieServerInfo.setServerId(kieserverID);
kieServerInfo.setLocation(controlerLocation);
kieServerInfo.setCapabilities(new ArrayList<>());
kieServerInfo.getCapabilities().add("BRM");
ResponseEntity<KieServerSetup> response = restTemplateKiewb
.execute(completeurl, HttpMethod.PUT, requestCallback(kieServerInfo, username, password), clientHttpResponse -> {
KieServerSetup extractedResponse = null;
ResponseEntity<KieServerSetup> extractedValue=null;
if (clientHttpResponse.getBody() != null) {
Scanner s = new Scanner(clientHttpResponse.getBody()).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
if (result==null || result.length()==0){
}else {
extractedResponse = mapper.readValue(result, KieServerSetup.class);
extractedValue = new ResponseEntity<>(extractedResponse, clientHttpResponse.getHeaders(), clientHttpResponse.getStatusCode());
}
}
return extractedValue;
});
if (response!= null) {
return response.getBody();
}else {
return null;
}
}
private RequestCallback requestCallback(final Object content, String username, String password) {
return clientHttpRequest -> {
if (content != null) {
if (content instanceof KieServerInfo) {
KieServerInfo kieServerSetup = (KieServerInfo) content;
mapper.writeValue(clientHttpRequest.getBody(), kieServerSetup);
} else {
mapper.writeValue(clientHttpRequest.getBody(), content);
}
}
clientHttpRequest.getHeaders().add(
HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
clientHttpRequest.getHeaders().add(
HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
String auth = username + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(Charset.forName("UTF-8")));
String authHeader = "Basic " + new String(encodedAuth);
clientHttpRequest.getHeaders().add(
HttpHeaders.AUTHORIZATION, authHeader);
};
}
}

View file

@ -0,0 +1,49 @@
package org.chtijbug.drools.console.service.wbconnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.nio.charset.Charset;
class LoggingRequestResponseLoggingInterceptor implements ClientHttpRequestInterceptor {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
logRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
logResponse(response);
return response;
}
private void logRequest(HttpRequest request, byte[] body) throws IOException {
log.info("===========================request begin================================================");
log.info("URI : {}", request.getURI());
log.info("Method : {}", request.getMethod());
log.info("Headers : {}", request.getHeaders());
log.info("Request body: {}", new String(body, "UTF-8"));
log.info("==========================request end================================================");
}
private void logResponse(ClientHttpResponse response) throws IOException {
log.info("============================response begin==========================================");
log.info("Status code : {}", response.getStatusCode());
log.info("Status text : {}", response.getStatusText());
log.info("Headers : {}", response.getHeaders());
log.info("Response body: {}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
log.info("=======================response end=================================================");
}
}

View file

@ -15,7 +15,7 @@ import java.util.Optional;
@Push(PushMode.AUTOMATIC)
@StyleSheet("css/accueil.css")
@HtmlImport("frontend://styles/shared-styles.html")
@Route("accueil")
@Route("admin/accueil")
public class AccueilView extends SqueletteComposant implements BeforeEnterObserver {

View file

@ -7,8 +7,9 @@ kie-wb.password=admin
adminConsole.tmpdir=/tmp
org.kie.server.controller=http://localhost:18080/kie-wb/rest
org.kie.server.location=http://localhost:8200/api/server
org.kie.server.id=pymmaConsole2
spring.data.mongodb.database=businessProxyDB
spring.data.mongodb.host=localhost:28017