How to add an addiitional health metric? - jhipster

trying to add an additional health metric in my jhipster app.. what elase do I need to do other than the following ?
#Component
#RestControllerEndpoint(id="xxx")
public class CustomActuatorEndpoint {
#GetMapping("/management/health/xxx")
public #ResponseBody
ResponseEntity customEndPoint(){
return new ResponseEntity<>("REST end point", HttpStatus.OK);
}
}

Related

Accessing test context data in custom cucumber formatter/listener

I am creating some kind of custom reporting with cucumber with custom listener/formatter. but I am unable to add some data from test context to my report.
I know we share data/state between steps using cucumber-picocontainer, but my question is how can I access test context data from the custom listener/formatter that i am writing?
Cucumber-Java : 5.2.0
Update: Adding more details. is there a way i can use use context object in the custom listener/plugin. i would like to context.setFailMessage(""); from the custom listener.
Thanks,
Vikas
In order to create custom reporting in cucumber, you have to follow the below steps.
Step 1: Implement ConcurrentEventListener interface
public class DesktopStepDisplayer implements ConcurrentEventListener
Step 2: Add the implementation in EventHandler as show below
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Step 3: Set the event publisher
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
Entire Script:
public class DesktopStepDisplayer implements ConcurrentEventListener {
private EventHandler<TestStepStarted> eventHandler = new EventHandler<TestStepStarted>()
{
public void receive(TestStepStarted event)
{
if(event.getTestStep() instanceof PickleStepTestStep)
{
String message = ((PickleStepTestStep)event.getTestStep()).getStep().getText();
}
};
public void setEventPublisher(EventPublisher publisher) {
publisher.registerHandlerFor(TestStepStarted.class, eventHandler);
}
}

Adding custom dimension to Application Insights traces from .NET Core

How to add custom dimension to Application Insights traces from .NET Core?
Any pointers are welcome.
If it's a .net core web project, you can use ITelemetryInitializer to add custom dimension.
First, add a new class named MyTelemetryInitializer to the project:
public class MyTelemetryInitializer: ITelemetryInitializer
{
public MyTelemetryInitializer()
{
}
public void Initialize(ITelemetry telemetry)
{
if (telemetry is TraceTelemetry traceTelemetry)
{
if (!traceTelemetry.Properties.ContainsKey("my_custom_1"))
{
//add the custom dimension here
traceTelemetry.Properties["my_custom_1"] = "test 12346";
}
}
}
}
Then in the Startup.cs -> ConfigureServices method, add these lines of code:
services.AddApplicationInsightsTelemetry();
services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();
And for testing purpose, in the HomeController, I have this Index method to send trace message:
public IActionResult Index()
{
TelemetryClient client = new TelemetryClient();
client.TrackTrace("it is a trace message from index page");
return View();
}
At last, run the project. Then nav to azure portal -> application insights, you can see the custom dimension is added.
better cast to ISupportProperties
if (telemetry is ISupportProperties traceTelemetry)

Broadleaf: error in execting custom service

Hi I Have Created a Custom Service to Save Custom objects and using existing objects but after running the application the following error will be displaying in server console and stops the application to start
Here is my code for custom service :
#Service
public class FilterExtra {
// #Autowired
#Resource(name="org.broadleafcommerce.core.search.domain.FieldImpl")
FieldImpl f;
// #Autowired
#Resource(name="org.broadleafcommerce.core.catalog.domain.Product")
Product p;
public static String nme="";
#PersistenceContext(unitName = "blPU")
public EntityManager em;
ProductAttribute pa;
#SuppressWarnings("unchecked")
public String check1(String name) {
Query q=em.createQuery("SELECT * FROM PRODUCT_ATTRIBUTE WHERE NAME=:name");
q.setParameter("name", name);
List<ProductAttribute> inf0 = q.getResultList();
System.out.println(inf0);
if(inf0!=null)
{
f.setFriendlyName(name);
f.setAbbreviation(name);
f.setEntityType(p.getFieldEntityType());
f.setPropertyName("productAttributes("+name+").value");
em.merge(f);
}
if(name.equals(nme))
{
return name;
}
else {
return null;
}
}
}
here is my XML file:
screen shot of xml file:
http://i.prntscr.com/wkVH2q8MQBmAeJ26BfEvZw.png
here is server log for error:
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-11-23 09:59:43.881 ERROR 3827 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
A component required a bean named 'org.broadleafcommerce.core.search.domain.FieldImpl' that could not be found.
Action:
Consider defining a bean named 'org.broadleafcommerce.core.search.domain.FieldImpl' in your configuration.
Please Help me to Solve the issue
Thanks in Advance

How can microservice can talk to other microservice in JHipster

I am planning to create a microservice aplication with a dedicated service for dealing with data (mostly a Mongodb based service). I am wondering if there is a way using which my other microservices will be able to communicate with this service to make use of the shared data. Is it possible with JHipster API Gateway ?
If not how can I achieve this. I dont want to keep multiple copies of the same data within each microservice.
You can also use Feign clients with JHipster.
Annotate your SpringBootApplication with #EnableFeignClients
...
import org.springframework.cloud.openfeign.EnableFeignClients;
...
#SpringBootApplication
#EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
#EnableDiscoveryClient
#EnableFeignClients
public class MyApp {
...
}
Create a Feign client in your microservice
...
import org.springframework.cloud.openfeign.FeignClient;
...
#FeignClient("another-service")
public interface AnotherClient {
#RequestMapping(method = RequestMethod.GET, value = "/api/another")
List<AnotherDTO> getAll();
}
Inject the Feign client with #Autowired and call it. It should be ready to use.
#RestController
#RequestMapping("/api")
public class MyResource {
...
#Autowired
private AnotherClient anotherClient;
...
#GetMapping("/another")
#Timed
public List<AnotherDTO> getAll() {
log.debug("REST request to get all");
return anotherClient.getAll();
}
}
For us, it worked without implementing a ClientHttpRequestInterceptor and setting a JWT token.
You can register your microservices to the same registry and then they can call each other.
UPDATE : Here is how I made it work.
In the microservice consuming the data one, use RestTemplate with the current user's jwt-token in the Authorization-header for the API calls :
#Component
public class AuthenticateClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
#Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
String token = SecurityUtils.getCurrentUserJWT();
httpRequest.getHeaders().add("Authorization","Bearer "+token);
return clientHttpRequestExecution.execute( httpRequest, bytes );
}
}
My custom restTemplate using ClientHttpRequestInterceptor for adding token in header.
#Configuration
public class CustomBean {
#Autowired
AuthenticateClientHttpRequestInterceptor interceptor;
#Bean
#LoadBalanced
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(interceptor));
return restTemplate;
}
}
And in the resource controller where your are making the call for data:
#RestController
#RequestMapping("/api")
public class DataResource {
#Autowired
RestTemplate restTemplate;
#PostMapping("/hello")
#Timed
public ResponseEntity<Hello> createHello(#RequestBody Hello Hello) throws URISyntaxException {
//The name your data micro service registrated in the Jhipster Registry
String dataServiceName = "data_micro_service";
URI uri = UriComponentsBuilder.fromUriString("//" + dataServiceName + "/api/datas")
.build()
.toUri();
//call the data microservice apis
List<Data> result = restTemplate.getForObject(uri, Data[].class);
return ResponseEntity.created(new URI("/api/hellos/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
}
Typically microservices talk to each other. Thats the whole point. With Eureka discovery in place you simply call the microservice by name instead of the FQDN which we normally would use without microservice.
For e.g. your book-service will call the author-service like this
http://author-service/authors
full example here https://spring.io/blog/2015/01/20/microservice-registration-and-discovery-with-spring-cloud-and-netflix-s-eureka
Please don't forget that JHipster is an opinionated framework based off of Spring Cloud so you can find most of this stuff by searching Spring docs.
you can use below solution :
Microservice A (i.e UAA-SERVICE), and Microservice B
Microservice B want to connect microservice A and call services with Feign client.
1)This code for Microservice B
Client proxy :- #AuthorizedFeignClient(name = "UAA-SERVICE")
#AuthorizedFeignClient(name = "UAA-SERVICE")
public interface UaaServiceClient {
#RequestMapping(method = RequestMethod.GET, path = "api/users")
public List<UserDTO> getUserList();
#RequestMapping(method = RequestMethod.PUT, path = "api/user-info")
public String updateUserInfo(#RequestBody UserDTO userDTO);
}
UAA-SERVICE : find this name with running Application Instances with registry.
2) In Microservice B (application.yml)
Increase feign client connection Time Out:
feign:
client:
config:
default:
connectTimeout: 10000
readTimeout: 50000
Increase hystrix Thread time out:-
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 60000
shareSecurityContext: true
3) add #EnableFeignClients in main #SpringBootApplication class.
This solution is working fine for me.

Spring Integration Cassandra persistence workflow

I try to realize the following workflow with Spring Integration:
1) Poll REST API
2) store the POJO in Cassandra cluster
It's my first try with Spring Integration, so I'm still a bit overwhelmed about the mass of information from the reference. After some research, I could make the following work.
1) Poll REST API
2) Transform mapped POJO JSON result into a string
3) save string into file
Here's the code:
#Configuration
public class ConsulIntegrationConfig {
#InboundChannelAdapter(value = "consulHttp", poller = #Poller(maxMessagesPerPoll = "1", fixedDelay = "1000"))
public String consulAgentPoller() {
return "";
}
#Bean
public MessageChannel consulHttp() {
return MessageChannels.direct("consulHttp").get();
}
#Bean
#ServiceActivator(inputChannel = "consulHttp")
MessageHandler consulAgentHandler() {
final HttpRequestExecutingMessageHandler handler =
new HttpRequestExecutingMessageHandler("http://localhost:8500/v1/agent/self");
handler.setExpectedResponseType(AgentSelfResult.class);
handler.setOutputChannelName("consulAgentSelfChannel");
LOG.info("Created bean'consulAgentHandler'");
return handler;
}
#Bean
public MessageChannel consulAgentSelfChannel() {
return MessageChannels.direct("consulAgentSelfChannel").get();
}
#Bean
public MessageChannel consulAgentSelfFileChannel() {
return MessageChannels.direct("consulAgentSelfFileChannel").get();
}
#Bean
#ServiceActivator(inputChannel = "consulAgentSelfFileChannel")
MessageHandler consulAgentFileHandler() {
final Expression directoryExpression = new SpelExpressionParser().parseExpression("'./'");
final FileWritingMessageHandler handler = new FileWritingMessageHandler(directoryExpression);
handler.setFileNameGenerator(message -> "../../agent_self.txt");
handler.setFileExistsMode(FileExistsMode.APPEND);
handler.setCharset("UTF-8");
handler.setExpectReply(false);
return handler;
}
}
#Component
public final class ConsulAgentTransformer {
#Transformer(inputChannel = "consulAgentSelfChannel", outputChannel = "consulAgentSelfFileChannel")
public String transform(final AgentSelfResult json) throws IOException {
final String result = new StringBuilder(json.toString()).append("\n").toString();
return result;
}
This works fine!
But now, instead of writing the object to a file, I want to store it in a Cassandra cluster with spring-data-cassandra. For that, I commented out the file handler in the config file, return the POJO in transformer and created the following, :
#MessagingGateway(name = "consulCassandraGateway", defaultRequestChannel = "consulAgentSelfFileChannel")
public interface CassandraStorageService {
#Gateway(requestChannel="consulAgentSelfFileChannel")
void store(AgentSelfResult agentSelfResult);
}
#Component
public final class CassandraStorageServiceImpl implements CassandraStorageService {
#Override
public void store(AgentSelfResult agentSelfResult) {
//use spring-data-cassandra repository to store
LOG.info("Received 'AgentSelfResult': {} in Cassandra cluster...");
LOG.info("Trying to store 'AgentSelfResult' in Cassandra cluster...");
}
}
But this seems to be a wrong approach, the service method is never triggered.
So my question is, what would be a correct approach for my usecase? Do I have to implement the MessageHandler interface in my service component, and use a #ServiceActivator in my config. Or is there something missing in my current "gateway-approach"?? Or maybe there is another solution, that I'm not able to see..
Like mentioned before, I'm new to SI, so this may be a stupid question...
Nevertheless, thanks a lot in advance!
It's not clear how you are wiring in your CassandraStorageService bean.
The Spring Integration Cassandra Extension Project has a message-handler implementation.
The Cassandra Sink in spring-cloud-stream-modules uses it with Java configuration so you can use that as an example.
So I finally made it work. All I needed to do was
#Component
public final class CassandraStorageServiceImpl implements CassandraStorageService {
#ServiceActivator(inputChannel="consulAgentSelfFileChannel")
#Override
public void store(AgentSelfResult agentSelfResult) {
//use spring-data-cassandra repository to store
LOG.info("Received 'AgentSelfResult': {}...");
LOG.info("Trying to store 'AgentSelfResult' in Cassandra cluster...");
}
}
The CassandraMessageHandler and the spring-cloud-streaming seemed to be a to big overhead to my use case, and I didn't really understand yet... And with this solution, I keep control over what happens in my spring component.

Resources