Using MSAL for Angular and NGXLogger - msal-angular

I recently upgraded my Angular application to use MSAL for Angular V2.X.
https://www.npmjs.com/package/#azure/msal-angular
My app uses NGXLogger for logging.
https://www.npmjs.com/package/ngx-logger
I am getting these errors when I run my app:
ERROR Error: Cannot instantiate cyclic dependency! NGXLogger
and
ERROR Error: Cannot instantiate cyclic dependency! ErrorHandler
NOTE: Update: MSAL for Angular is NOT using NGXLogger!!
It looks like MSAL for Angular now uses NGXLogger.
I am seeking guidance on how to fix the issue so MSAL for Angular and my app can use NGXLogger.

MSAL for Angular does not use NGXLogger.
The way I fixed the error was to remove the provider specified in the module and instead use provideIn: root for my ErrorHandler and my LoggerService (that uses NGXLogger)
#Injectable({
providedIn: 'root'
})
export class GlobalErrorHandler implements ErrorHandler {
and
import { NGXLogger } from 'ngx-logger';
import { Injectable } from '#angular/core';
import { HttpHeaders } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class LoggerService {

Related

Spring Boot Starter GraphQL OPTIONS Pre-Flight request rejected with HTTP 403

I've recently converted a GraphQL API from SpringBoot Web to WebFlux. In the previous version, the #RequestMapping was annotated with #CrossOrigin, which seemed to cover the OPTIONS HTTP verb.
In the new version, I am using the #MutationMapping / #QueryMapping annotations to map the schema to my methods, and responding to them reactively.
The problem is that for some of our frontend's, an OPTIONS preflight is sent and rejected with a 403 by this new implementation.
Is there an annotation or configuration I can enable where this preflight will not be rejected?
I've attempted to use the GraphQlWebFluxAutoConfiguration.GraphQlEndpointCorsConfiguration object however I can't seem to get it configured correctly. Any advice would be much appreciated, as I'm relatively new to the WebFlux stack.
Here's how I solved it - the issue was caused by my local dev environment having tomcat9, and the staging/qa environment I was deploying to having tomcat7 (not supporting WebFlux properly).
Please note that the app.enable-cors is a property defined in my application.properties file - you will need to add this if you are just copying+pasting this code.
I created two configuration classes, overriding both the Mvc and WebFlux Configurer.addCorsMapping(CorsRegistry registry) method. Depending on which auto configuration is loaded, the correct overriden method will be run. Code as follows:
First, the WebFlux version
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
#Configuration
#ConditionalOnProperty(name = "app.enable-cors", havingValue = "true")
public class GraphQLWebFluxConfiguration implements WebFluxConfigurer {
#Override
public void addCorsMappings(CorsRegistry corsRegistry){
corsRegistry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*");
}
}
Secondly the MVC version
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#ConditionalOnProperty(name = "app.enable-cors", havingValue = "true")
public class GraphQLWebMvcConfiguration implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry corsRegistry){
corsRegistry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*");
}
}
I obviously have this disabled for the prod environment, but as a workaround for your QA/local environment it works well.

"spring-boot-starter-web" compatibility with Quarkus

I'm new to Quarkus and I'm validating the migration viability of a quite complex Spring Boot application.
For now, I'm trying to make the first step into Quarkus world, which is to get the application running on Quarkus JVM (non native option) with as little changes as possible.
After dealing with "spring-orm", "spring-jdbc" and "spring-web" (client part) dependencies not covered by Quarkus spring extensions, now I'm facing the Quarkus build error below:
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:2.2.1.Final:build (default) on project rules-engine-core: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.arc.deployment.ArcProcessor#registerBeans threw an exception: java.lang.IllegalArgumentException: Producer method return type not found in index: org.springframework.boot.web.servlet.ServletRegistrationBean
After some research, I'm still lost about the truly right way to solve this problem that seems to be caused by code below:
import javax.ws.rs.core.Application;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.catalina.valves.StuckThreadDetectionValve;
import org.springframework.beans.factory.annotation.Autowired;
#Configuration
#SpringBootApplication( exclude = TransactionAutoConfiguration.class )
public class WebApplicationConfiguration extends SpringBootServletInitializer {
#Autowired
private [ApplicationName]ExecutorSemaphoreValve semaphoreValve;
// Replaces the need for web.xml
#Bean
public ServletRegistrationBean servletRegistrationBean( ApplicationContext context ) {
return new ServletRegistrationBean( new CXFServlet(), "/*" );
}
// Configure the embedded tomcat to use same settings as default standalone
// tomcat deploy
#Bean
public AbstractServletWebServerFactory embeddedServletContainerFactory() {
// Made to match the context path when deploying to standalone tomcat-
// can easily be kept in sync w/ properties
TomcatServletWebServerFactory factory =
new TomcatServletWebServerFactory( CorePropertyUtils.engineContext(), CorePropertyUtils.enginePort() );
StuckThreadDetectionValve stuckThreadValve = new StuckThreadDetectionValve();
semaphoreValve.setBlock( false );
semaphoreValve.setFairness( false );
factory.addContextValves( stuckThreadValve, semaphoreValve );
return factory;
}
// Used when deploying to a standalone servlet container, i.e. tomcat
#Override
protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
return application.sources( Application.class );
}
}
I've found a similar post here, but it was result of lack of Quarkus spring extensions addition, which I believe is not my case.
It's just a matter of jandex indexation?
Do I need to change the code that uses the 'spring-boot-web' dependencies? (I hope not, at least for first migration stage)
Thanks a lot and best regards!

Spring loading and using bean from module

I have divided my project into 3 modules- client, server, and core. In the core module, I defined the required settings for the sentry. I would like to use those beans in client and server modules so that I don't have to redefine them for each module.
Is it possible? If so please give example.
My current sentry setup in the core module.
org/project/core/configurations/SentryConfiguration.java
package org.project.core.configurations;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
#Configuration
public class SentryConfiguration {
/*
This class is constructed according official sentry documentation.
URL: https://docs.sentry.io/platforms/java/guides/spring/
*/
#Bean
public HandlerExceptionResolver sentryExceptionResolver() {
return new io.sentry.spring.SentryExceptionResolver();
}
#Bean
public ServletContextInitializer sentryServletContextInitializer() {
return new io.sentry.spring.SentryServletContextInitializer();
}
}

Spring Boot REST API not reachable in GCP

I am deploying the Spring Boot Rest API in Google Cloud Platform. The Rest API is running fine in my local while running the application as Spring boot application. But the same REST API URL is not recognized while deploying in GCP.
Project Structure:
app.yaml:
runtime: java
env: flex
runtime_config:
  jdk: openjdk8
handlers:
- url: /.*
script: this field is required, but ignored
GreetingController.java
package com.designdreamers.rest.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.designdreamers.rest.vo.Greeting;
#RestController
public class GreetingController {
private int idValue;
#RequestMapping(value="/greet")
public Greeting greeting(#RequestParam(value="content", defaultValue = "Hello World!!")String content){
Greeting greeting=new Greeting();
greeting.setId(idValue++);
greeting.setContent(content);
return greeting;
}
}
Application.java
package com.designdreamers.rest.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = "com.designdreamers.rest.controller")
public class Application {
public static void main(String args[]){
SpringApplication.run(Application.class,args);
}
}
Below is the REST API response that I get on running the application as Spring boot application in local.
URL :http://localhost:8080/greet
{"id":1,"content":"Hello World!!"}
I deployed the same application in GCP and on hitting the REST API URI, below is the error that we get.
URI: http://helloworld-001.appspot.com/greet
Error: Not Found
The requested URL /greet was not found on this server.
A helping hand on identifying the issue would be very helpful.

Whitelabel Error Page just type on URL?

This Spring-boot project is integrated with Angular 4. I can reach the home page when type the url adress >> localhost:8080.
I get whitelabel error page when type any diffent url is added parameter like: /login, /signup.
There was an unexpected error (type=Not Found, status=404).
I can reach these pages (localhost:8080/signup, localhost:8080/foo, ..) on website using angular-routing. So the problem is about only hitting url directly.
So How can I solve this, any idea to check would be helpful.
Note: There is no authorization for these url in server side.
Edit: index.html path added.
src/main/resources
static
assets
index.html
bundle
bundle
..
routing.ts
export const routes: Routes = [
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path:'signup',
component: SignupComponent,
canActivate: [GuestGuard],
pathMatch:'full'
},
Create a controller and forward every request to index.html as follows,
#RequestMapping({ "/signup", "/purchase", "/credit"})
public String index() {
return "forward:/index.html";
}
By doing this, angular will pickup the url and navigate to the corresponding pages. Also please modify the request urls as needed. Whenever a request is hit from browser directly, it will pickup by the spring boot and spring boot doesnt know the angular routing urls. To prevent this we need to forward all request to index.html.
Or you can use the Use HashLocationStrategy as #Vikas suggested
I have implemented directly this WebMvcConfigurer and it works perfectly for me. This is the reference link.
import java.io.IOException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*")
.addResourceLocations("classpath:/static/")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
#Override
protected Resource getResource(String resourcePath,
Resource location) throws IOException {
Resource requestedResource = location.createRelative(resourcePath);
return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
: new ClassPathResource("/static/index.html");
}
});
}
}

Resources