Skip to content

Commit

Permalink
fix: some minor bugs; filter out non-springboot app (#15)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
qiaoleiatms and actions-user authored May 9, 2023
1 parent 4cba621 commit cc58988
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 35 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The default output will be a json like
```javascript
[
{
"server": "127.0.0.1",
"server": "127.0.0.1",
// Application Name
"appName": "hellospring",
// Runnable artifact name
Expand All @@ -58,8 +58,8 @@ The default output will be a json like
"appType": "SpringBootFatJar",
// Runtime JDK Version
"runtimeJdkVersion": "17.0.6",
// OS Name
"OsName": "ubuntu",
// OS Name
"OsName": "ubuntu",
// OS Version
"OsVersion": "2204",
// Build JDK version
Expand Down Expand Up @@ -120,13 +120,13 @@ Only support to discover the spring apps from Linux VM

- More java app runtime are coming.

| Type | Readiness | Ready Date |
| -- | -- | -- |
| SpringBoot | Ready | 2023-04 |
| Tomcat App | Planned | - |
| WebLogic App | Planned | - |
| WebSphere App | Planned | - |
| JBoss EAP App | Planned | - |
| Type | Readiness | Ready Date |
|----------------| -- | -- |
| SpringBoot App | Ready | 2023-04 |
| Tomcat App | Planned | - |
| WebLogic App | Planned | - |
| WebSphere App | Planned | - |
| JBoss EAP App | Planned | - |

- More source operating systems are coming.

Expand Down
10 changes: 10 additions & 0 deletions springboot/core_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ func (s *springBootDiscoveryExecutor) Discover(ctx context.Context, serverConnec
errs = append(errs, errInLoop)
continue
}

if !Contains(SpringBootAppTypes, app.AppType) {
azureLogger.Info("not a valid springboot app", "appType", app.AppType)
continue
}

jarSize, _ := jar.GetSize()
app.LastUpdatedTime = time.Now()
app.JarSize = jarSize
Expand Down Expand Up @@ -299,6 +305,10 @@ func (s *springBootDiscoveryExecutor) tryConnect(ctx context.Context, serverConn

if cred, err = serverDiscovery.Prepare(); err != nil {
_ = serverDiscovery.Finish()
if IsCredentialError(err) {
// if credential error, the server is connectable, just break to avoid nonsense try
break
}
azureLogger.Warning(err, "failed to connect to", "server", info.Server)
continue
} else {
Expand Down
43 changes: 39 additions & 4 deletions springboot/core_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ var _ = Describe("Test springboot discovery executor", func() {
{appName: SpringBoot2xAppName, jdkVersion: Jdk7Version, springBootVersion: SpringBoot2xVersion, jarFileLocation: SpringBoot2xJarFileLocation, process: SpringBoot2xProcess},
} {
if testcase.appName != ExecutableAppName {
matchers = append(matchers, MatchFatJar(testcase.appName, testcase.jdkVersion, testcase.springBootVersion, testcase.jarFileLocation))
matchers = append(matchers, ContainElement(MatchFatJar(testcase.appName, testcase.jdkVersion, testcase.springBootVersion, testcase.jarFileLocation)))
} else {
matchers = append(matchers, MatchExecutableJar(testcase.appName, testcase.jarFileLocation))
matchers = append(matchers, Not(ContainElement(MatchExecutableJar(testcase.appName, testcase.jarFileLocation))))
}
processes = append(processes, testcase.process)
}

setupServerConnectorMock(serverConnector, strings.Join(processes, "\n"))
apps, err := executor.Discover(context.Background(), connection)
Expect(apps).Should(ContainElements(matchers))
Expect(apps).Should(And(matchers...))
Expect(err).Should(BeNil())
})
})
Expand Down Expand Up @@ -137,6 +137,41 @@ var _ = Describe("Test springboot discovery executor", func() {
})
})

When("primary fqdn is accessible but got credential error", func() {
It("prepare should be failed with credential error", func() {
var primaryFqdn = "primary"
var altServerAccessible = "server-accessible"

for _, testcase := range []struct {
fqdn string
accessible bool
}{
{fqdn: primaryFqdn, accessible: true},
{fqdn: altServerAccessible, accessible: false},
} {
connector := NewMockServerConnector(ctrl)
connector.EXPECT().FQDN().Return(testcase.fqdn).AnyTimes()
if !testcase.accessible {
connector.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(fmt.Errorf("connection failed")).AnyTimes()
} else {
connector.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(fmt.Errorf("ssh: unable to authenticate")).AnyTimes()
}

setupServerConnectorMock(connector, strings.Join([]string{SpringBoot2xProcess, SpringBoot1xProcess, ExecutableProcess}, "\n"))
serverConnectorFactory.EXPECT().Create(gomock.Any(), testcase.fqdn, gomock.Any()).Return(connector).AnyTimes()
}

credentialProvider.EXPECT().GetCredentials().Return(credentials, nil).AnyTimes()

connection := ServerConnectionInfo{Server: primaryFqdn, Port: 1022}
accessible := ServerConnectionInfo{Server: altServerAccessible, Port: 1022}
apps, err := executor.Discover(context.Background(), connection, accessible)

Expect(apps).Should(BeEmpty())
Expect(err).Should(BeAssignableToTypeOf(CredentialError{}))
})
})

When("get credentials error", func() {
It("discovery should be failed", func() {
serverConnectorFactory.EXPECT().Create(gomock.Any(), gomock.Any(), gomock.Any()).Return(serverConnector).AnyTimes()
Expand Down Expand Up @@ -249,7 +284,7 @@ func MatchExecutableJar(app string, jarLocation string) types.GomegaMatcher {
}

func setupServerConnectorMock(s *MockServerConnector, processes string) {
s.EXPECT().Close().MinTimes(1)
s.EXPECT().Close().AnyTimes()
s.EXPECT().RunCmd(gomock.Eq(GetLocateJarCmd(SpringBoot2xProcessId, SpringBoot2xJarFile))).Return(SpringBoot2xJarFileLocation, nil).AnyTimes()
s.EXPECT().RunCmd(gomock.Eq(GetEnvCmd(SpringBoot2xProcessId))).Return(TestEnv, nil).AnyTimes()
s.EXPECT().RunCmd(gomock.Eq(GetPortsCmd(SpringBoot2xProcessId))).Return(Ports, nil).AnyTimes()
Expand Down
2 changes: 1 addition & 1 deletion springboot/server_connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (s *linuxServer) Connect(username, password string) error {
connectString := fmt.Sprintf("%s:%d", s.server, s.port)
client, err := ssh.Dial("tcp", connectString, cfg)
if err != nil {
return ConnectionError{error: err, message: fmt.Sprintf("error dial %s", connectString)}
return err
}
s.mux.Lock()
defer s.mux.Unlock()
Expand Down
28 changes: 15 additions & 13 deletions springboot/server_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,27 +269,29 @@ func (l *linuxServerDiscovery) connect(creds ...*Credential) (*Credential, error
}

results, _ :=
ToSlice[loginResult](s.Map(func(cred *Credential) loginResult {
err := l.server.Connect(cred.Username, cred.Password)
if err != nil {
if !isAuthFailure(err) {
return loginResult{cred: nil, err: err}
}
}
return loginResult{cred: cred, err: nil}
}))
ToSlice[loginResult](
s.Map(func(cred *Credential) loginResult {
err := l.server.Connect(cred.Username, cred.Password)
return loginResult{cred: cred, err: err}
}),
)

var err error
for _, result := range results {
if result.cred != nil {
return result.cred, nil
if result.err != nil {
if isAuthFailure(result.err) {
err = CredentialError{error: result.err, message: fmt.Sprintf("bad credential: %s", result.cred.Username)}
} else {
err = ConnectionError{error: result.err, message: fmt.Sprintf("failed connect to %s", l.server.FQDN())}
}
continue
}
err = result.err
return result.cred, nil
}

if err != nil {
azureLogger.Warning(err, "error to connect to server with credential", "server", l.server.FQDN())
return nil, ConnectionError{error: err, message: fmt.Sprintf("failed to connect to server: %s", l.server.FQDN())}
return nil, err
}

return nil, CredentialError{
Expand Down
13 changes: 7 additions & 6 deletions springboot/server_discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ var _ = Describe("Linux java process", func() {
errorCall(call)
}
credentialProvider.EXPECT().GetCredentials().Return(credentials, nil)
Expect(executor.Prepare()).Error().Should(BeAssignableToTypeOf(ConnectionError{}))
_, err := executor.Prepare()
Expect(err).Should(BeAssignableToTypeOf(ConnectionError{}))
})
})

Expand Down Expand Up @@ -366,14 +367,14 @@ var _ = Describe("Linux java process", func() {

When("multiple credentials get, when auth error occurred for all", func() {
It("should failed with credential error", func() {
for i, cred := range credentials {
for _, cred := range credentials {
call := m.EXPECT().Connect(gomock.Eq(cred.Username), gomock.Any()).MaxTimes(1)
if i%2 == 0 {
unauthenticated(call)
}
unauthenticated(call)
}
credentialProvider.EXPECT().GetCredentials().Return(credentials, nil)
Expect(executor.Prepare()).Error().Should(BeNil())
cred, err := executor.Prepare()
Expect(cred).Should(BeNil())
Expect(isAuthFailure(err)).Should(BeTrue())
})
})
})
Expand Down
2 changes: 1 addition & 1 deletion springboot/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func CleanOutput(raw string) string {
return value
}

func Contains(slices []string, find string) bool {
func Contains[T ~string](slices []T, find T) bool {
for _, t := range slices {
if t == find {
return true
Expand Down

0 comments on commit cc58988

Please sign in to comment.