mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss
This commit is contained in:
commit
6915bd7e6a
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/deps"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/console"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/deps"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/console"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.List;
|
||||
|
||||
public interface ITileScanListener {
|
||||
boolean onTileChange(Rectangle rowMergedRect, int row, int col);
|
||||
void onRegionChange(List<Region> regionList);
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
// logger facility for dynamic switch between console logger used in Applet and log4j based logger
|
||||
public class Logger {
|
||||
private static LoggerFactory factory = null;
|
||||
|
||||
public static final int LEVEL_TRACE = 1;
|
||||
public static final int LEVEL_DEBUG = 2;
|
||||
public static final int LEVEL_INFO = 3;
|
||||
public static final int LEVEL_WARN = 4;
|
||||
public static final int LEVEL_ERROR = 5;
|
||||
|
||||
private Class<?> clazz;
|
||||
private Logger logger;
|
||||
|
||||
private static int level = LEVEL_INFO;
|
||||
|
||||
public static Logger getLogger(Class<?> clazz) {
|
||||
return new Logger(clazz);
|
||||
}
|
||||
|
||||
public static void setFactory(LoggerFactory f) {
|
||||
factory = f;
|
||||
}
|
||||
|
||||
public static void setLevel(int l) {
|
||||
level = l;
|
||||
}
|
||||
|
||||
public Logger(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
protected Logger() {
|
||||
}
|
||||
|
||||
public boolean isTraceEnabled() {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
return logger.isTraceEnabled();
|
||||
}
|
||||
return level <= LEVEL_TRACE;
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled() {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
return logger.isDebugEnabled();
|
||||
}
|
||||
return level <= LEVEL_DEBUG;
|
||||
}
|
||||
|
||||
public boolean isInfoEnabled() {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
return logger.isInfoEnabled();
|
||||
}
|
||||
return level <= LEVEL_INFO;
|
||||
}
|
||||
|
||||
public void trace(Object message) {
|
||||
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.trace(message);
|
||||
} else {
|
||||
if(level <= LEVEL_TRACE)
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void trace(Object message, Throwable exception) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.trace(message, exception);
|
||||
} else {
|
||||
if(level <= LEVEL_TRACE) {
|
||||
System.out.println(message);
|
||||
if (exception != null) {
|
||||
exception.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void info(Object message) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.info(message);
|
||||
} else {
|
||||
if(level <= LEVEL_INFO)
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void info(Object message, Throwable exception) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.info(message, exception);
|
||||
} else {
|
||||
if(level <= LEVEL_INFO) {
|
||||
System.out.println(message);
|
||||
if (exception != null) {
|
||||
exception.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(Object message) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.debug(message);
|
||||
} else {
|
||||
if(level <= LEVEL_DEBUG)
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(Object message, Throwable exception) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.debug(message, exception);
|
||||
} else {
|
||||
if(level <= LEVEL_DEBUG) {
|
||||
System.out.println(message);
|
||||
if (exception != null) {
|
||||
exception.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(Object message) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.warn(message);
|
||||
} else {
|
||||
if(level <= LEVEL_WARN)
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(Object message, Throwable exception) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.warn(message, exception);
|
||||
} else {
|
||||
if(level <= LEVEL_WARN) {
|
||||
System.out.println(message);
|
||||
if (exception != null) {
|
||||
exception.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void error(Object message) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.error(message);
|
||||
} else {
|
||||
if(level <= LEVEL_ERROR)
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void error(Object message, Throwable exception) {
|
||||
if(factory != null) {
|
||||
if(logger == null)
|
||||
logger = factory.getLogger(clazz);
|
||||
|
||||
logger.error(message, exception);
|
||||
} else {
|
||||
if(level <= LEVEL_ERROR) {
|
||||
System.out.println(message);
|
||||
if (exception != null) {
|
||||
exception.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
public interface LoggerFactory {
|
||||
Logger getLogger(Class<?> clazz);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Region {
|
||||
private Rectangle bound;
|
||||
private List<Rectangle> rectList;
|
||||
|
||||
public Region() {
|
||||
bound = new Rectangle(0, 0, 0, 0);
|
||||
rectList = new ArrayList<Rectangle>();
|
||||
}
|
||||
|
||||
public Region(Rectangle rect) {
|
||||
bound = new Rectangle(rect.x, rect.y, rect.width, rect.height);
|
||||
rectList = new ArrayList<Rectangle>();
|
||||
rectList.add(rect);
|
||||
}
|
||||
|
||||
public Rectangle getBound() {
|
||||
return bound;
|
||||
}
|
||||
|
||||
public void clearBound() {
|
||||
assert(rectList.size() == 0);
|
||||
bound.x = bound.y = bound.width = bound.height = 0;
|
||||
}
|
||||
|
||||
public List<Rectangle> getRectangles() {
|
||||
return rectList;
|
||||
}
|
||||
|
||||
public boolean add(Rectangle rect) {
|
||||
if(bound.isEmpty()) {
|
||||
assert(rectList.size() == 0);
|
||||
bound.x = rect.x;
|
||||
bound.y = rect.y;
|
||||
bound.width = rect.width;
|
||||
bound.height = rect.height;
|
||||
|
||||
rectList.add(rect);
|
||||
return true;
|
||||
}
|
||||
|
||||
Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y- 1, rect.width + 2, rect.height + 2);
|
||||
if(!bound.intersects(rcInflated))
|
||||
return false;
|
||||
|
||||
for(Rectangle r : rectList) {
|
||||
if(r.intersects(rcInflated)) {
|
||||
if(!r.contains(rect)) {
|
||||
enlargeBound(rect);
|
||||
rectList.add(rect);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void enlargeBound(Rectangle rect) {
|
||||
int boundLeft = Math.min(bound.x, rect.x);
|
||||
int boundTop = Math.min(bound.y, rect.y);
|
||||
int boundRight = Math.max(bound.x + bound.width, rect.x + rect.width);
|
||||
int boundBottom = Math.max(bound.y + bound.height, rect.y + rect.height);
|
||||
|
||||
bound.x = boundLeft;
|
||||
bound.y = boundTop;
|
||||
bound.width = boundRight - boundLeft;
|
||||
bound.height = boundBottom - boundTop;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RegionClassifier {
|
||||
private List<Region> regionList;
|
||||
|
||||
public RegionClassifier() {
|
||||
regionList = new ArrayList<Region>();
|
||||
}
|
||||
|
||||
public void add(Rectangle rect) {
|
||||
// quickly identify that if we need a new region
|
||||
boolean newRegion = true;
|
||||
Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y - 1, rect.width + 2, rect.height + 2);
|
||||
for(Region region : regionList) {
|
||||
if(region.getBound().intersects(rcInflated)) {
|
||||
newRegion = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(newRegion) {
|
||||
regionList.add(new Region(rect));
|
||||
} else {
|
||||
for(Region region : regionList) {
|
||||
if(region.add(rect))
|
||||
return;
|
||||
}
|
||||
regionList.add(new Region(rect));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Region> getRegionList() {
|
||||
return regionList;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
regionList.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
public class TileInfo {
|
||||
private int row;
|
||||
private int col;
|
||||
private Rectangle tileRect;
|
||||
|
||||
public TileInfo(int row, int col, Rectangle tileRect) {
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
this.tileRect = tileRect;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public void setRow(int row) {
|
||||
this.row = row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public void setCol(int col) {
|
||||
this.col = col;
|
||||
}
|
||||
|
||||
public Rectangle getTileRect() {
|
||||
return tileRect;
|
||||
}
|
||||
|
||||
public void setTileRect(Rectangle tileRect) {
|
||||
this.tileRect = tileRect;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.cloud.consoleproxy.util;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TileTracker {
|
||||
|
||||
// 2 dimension tile status snapshot, a true value means the corresponding tile has been invalidated
|
||||
private boolean[][] snapshot;
|
||||
|
||||
private int tileWidth = 0;
|
||||
private int tileHeight = 0;
|
||||
private int trackWidth = 0;
|
||||
private int trackHeight = 0;
|
||||
|
||||
public TileTracker() {
|
||||
}
|
||||
|
||||
public int getTileWidth() {
|
||||
return tileWidth;
|
||||
}
|
||||
|
||||
public void setTileWidth(int tileWidth) {
|
||||
this.tileWidth = tileWidth;
|
||||
}
|
||||
|
||||
public int getTileHeight() {
|
||||
return tileHeight;
|
||||
}
|
||||
|
||||
public void setTileHeight(int tileHeight) {
|
||||
this.tileHeight = tileHeight;
|
||||
}
|
||||
|
||||
public int getTrackWidth() {
|
||||
return trackWidth;
|
||||
}
|
||||
|
||||
public void setTrackWidth(int trackWidth) {
|
||||
this.trackWidth = trackWidth;
|
||||
}
|
||||
|
||||
public int getTrackHeight() {
|
||||
return trackHeight;
|
||||
}
|
||||
|
||||
public void setTrackHeight(int trackHeight) {
|
||||
this.trackHeight = trackHeight;
|
||||
}
|
||||
|
||||
public void initTracking(int tileWidth, int tileHeight, int trackWidth, int trackHeight) {
|
||||
assert(tileWidth > 0);
|
||||
assert(tileHeight > 0);
|
||||
assert(trackWidth > 0);
|
||||
assert(trackHeight > 0);
|
||||
assert(tileWidth <= trackWidth);
|
||||
assert(tileHeight <= trackHeight);
|
||||
|
||||
this.tileWidth = tileWidth;
|
||||
this.tileHeight = tileHeight;
|
||||
this.trackWidth = trackWidth;
|
||||
this.trackHeight = trackHeight;
|
||||
|
||||
int cols = getTileCols();
|
||||
int rows = getTileRows();
|
||||
snapshot = new boolean[rows][cols];
|
||||
for(int i = 0; i < rows; i++)
|
||||
for(int j = 0; j < cols; j++)
|
||||
snapshot[i][j] = false;
|
||||
}
|
||||
|
||||
public synchronized void resize(int trackWidth, int trackHeight) {
|
||||
assert(tileWidth > 0);
|
||||
assert(tileHeight > 0);
|
||||
assert(trackWidth > 0);
|
||||
assert(trackHeight > 0);
|
||||
|
||||
this.trackWidth = trackWidth;
|
||||
this.trackHeight = trackHeight;
|
||||
|
||||
int cols = getTileCols();
|
||||
int rows = getTileRows();
|
||||
snapshot = new boolean[rows][cols];
|
||||
for(int i = 0; i < rows; i++)
|
||||
for(int j = 0; j < cols; j++)
|
||||
snapshot[i][j] = true;
|
||||
}
|
||||
|
||||
public void invalidate(Rectangle rect) {
|
||||
setTileFlag(rect, true);
|
||||
}
|
||||
|
||||
public void validate(Rectangle rect) {
|
||||
setTileFlag(rect, false);
|
||||
}
|
||||
|
||||
public List<TileInfo> scan(boolean init) {
|
||||
List<TileInfo> l = new ArrayList<TileInfo>();
|
||||
|
||||
synchronized(this) {
|
||||
for(int i = 0; i < getTileRows(); i++) {
|
||||
for(int j = 0; j < getTileCols(); j++) {
|
||||
if(init || snapshot[i][j]) {
|
||||
Rectangle rect = new Rectangle();
|
||||
rect.y = i*tileHeight;
|
||||
rect.x = j*tileWidth;
|
||||
rect.width = Math.min(trackWidth - rect.x, tileWidth);
|
||||
rect.height = Math.min(trackHeight - rect.y, tileHeight);
|
||||
|
||||
l.add(new TileInfo(i, j, rect));
|
||||
snapshot[i][j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasFullCoverage() {
|
||||
synchronized(this) {
|
||||
for(int i = 0; i < getTileRows(); i++) {
|
||||
for(int j = 0; j < getTileCols(); j++) {
|
||||
if(!snapshot[i][j])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void initCoverageTest() {
|
||||
synchronized(this) {
|
||||
for(int i = 0; i < getTileRows(); i++) {
|
||||
for(int j = 0; j < getTileCols(); j++) {
|
||||
snapshot[i][j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// listener will be called while holding the object lock, use it
|
||||
// with care to avoid deadlock condition being formed
|
||||
public synchronized void scan(int nStartRow, int nStartCol, ITileScanListener listener) {
|
||||
assert(listener != null);
|
||||
|
||||
int cols = getTileCols();
|
||||
int rows = getTileRows();
|
||||
|
||||
nStartRow = nStartRow % rows;
|
||||
nStartCol = nStartCol % cols;
|
||||
|
||||
int nPos = nStartRow*cols + nStartCol;
|
||||
int nUnits = rows*cols;
|
||||
int nStartPos = nPos;
|
||||
int nRow;
|
||||
int nCol;
|
||||
do {
|
||||
nRow = nPos / cols;
|
||||
nCol = nPos % cols;
|
||||
|
||||
if(snapshot[nRow][nCol]) {
|
||||
int nEndCol = nCol;
|
||||
for(; nEndCol < cols && snapshot[nRow][nEndCol]; nEndCol++) {
|
||||
snapshot[nRow][nEndCol] = false;
|
||||
}
|
||||
|
||||
Rectangle rect = new Rectangle();
|
||||
rect.y = nRow*tileHeight;
|
||||
rect.height = tileHeight;
|
||||
rect.x = nCol*tileWidth;
|
||||
rect.width = (nEndCol - nCol)*tileWidth;
|
||||
|
||||
if(!listener.onTileChange(rect, nRow, nEndCol))
|
||||
break;
|
||||
}
|
||||
|
||||
nPos = (nPos + 1) % nUnits;
|
||||
} while(nPos != nStartPos);
|
||||
}
|
||||
|
||||
public void capture(ITileScanListener listener) {
|
||||
assert(listener != null);
|
||||
|
||||
int cols = getTileCols();
|
||||
int rows = getTileRows();
|
||||
|
||||
RegionClassifier classifier = new RegionClassifier();
|
||||
int left, top, right, bottom;
|
||||
|
||||
synchronized(this) {
|
||||
for(int i = 0; i < rows; i++) {
|
||||
top = i*tileHeight;
|
||||
bottom = Math.min(top + tileHeight, trackHeight);
|
||||
for(int j = 0; j < cols; j++) {
|
||||
left = j*tileWidth;
|
||||
right = Math.min(left + tileWidth, trackWidth);
|
||||
|
||||
if(snapshot[i][j]) {
|
||||
snapshot[i][j] = false;
|
||||
classifier.add(new Rectangle(left, top, right - left, bottom - top));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
listener.onRegionChange(classifier.getRegionList());
|
||||
}
|
||||
|
||||
private synchronized void setTileFlag(Rectangle rect, boolean flag) {
|
||||
int nStartTileRow;
|
||||
int nStartTileCol;
|
||||
int nEndTileRow;
|
||||
int nEndTileCol;
|
||||
|
||||
int cols = getTileCols();
|
||||
int rows = getTileRows();
|
||||
|
||||
if(rect != null) {
|
||||
nStartTileRow = Math.min(getTileYPos(rect.y), rows - 1);
|
||||
nStartTileCol = Math.min(getTileXPos(rect.x), cols - 1);
|
||||
nEndTileRow = Math.min(getTileYPos(rect.y + rect.height - 1), rows -1);
|
||||
nEndTileCol = Math.min(getTileXPos(rect.x + rect.width - 1), cols -1);
|
||||
} else {
|
||||
nStartTileRow = 0;
|
||||
nStartTileCol = 0;
|
||||
nEndTileRow = rows - 1;
|
||||
nEndTileCol = cols - 1;
|
||||
}
|
||||
|
||||
for(int i = nStartTileRow; i <= nEndTileRow; i++)
|
||||
for(int j = nStartTileCol; j <= nEndTileCol; j++)
|
||||
snapshot[i][j] = flag;
|
||||
}
|
||||
|
||||
private int getTileRows() {
|
||||
return (trackHeight + tileHeight - 1) / tileHeight;
|
||||
}
|
||||
|
||||
private int getTileCols() {
|
||||
return (trackWidth + tileWidth - 1) / tileWidth;
|
||||
}
|
||||
|
||||
private int getTileXPos(int x) {
|
||||
return x / tileWidth;
|
||||
}
|
||||
|
||||
public int getTileYPos(int y) {
|
||||
return y / tileHeight;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* A <code>BuffereImageCanvas</code> component represents frame buffer image on the
|
||||
* screen. It also notifies its subscribers when screen is repainted.
|
||||
*/
|
||||
public class BufferedImageCanvas extends Canvas {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// Offline screen buffer
|
||||
private BufferedImage offlineImage;
|
||||
|
||||
// Cached Graphics2D object for offline screen buffer
|
||||
private Graphics2D graphics;
|
||||
|
||||
private PaintNotificationListener listener;
|
||||
|
||||
public BufferedImageCanvas(PaintNotificationListener listener, int width, int height) {
|
||||
super();
|
||||
this.listener = listener;
|
||||
|
||||
setBackground(Color.black);
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
// Don't intercept TAB key
|
||||
setFocusTraversalKeysEnabled(false);
|
||||
|
||||
setCanvasSize(width, height);
|
||||
}
|
||||
|
||||
public void setCanvasSize(int width, int height) {
|
||||
this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
graphics = offlineImage.createGraphics();
|
||||
|
||||
setSize(offlineImage.getWidth(), offlineImage.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Graphics g) {
|
||||
// Call paint() directly, without clearing screen first
|
||||
paint(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
// Only part of image, requested with repaint(Rectangle), will be
|
||||
// painted on screen.
|
||||
g.drawImage(offlineImage, 0, 0, this);
|
||||
|
||||
// Notify server that update is painted on screen
|
||||
listener.imagePaintedOnScreen();
|
||||
}
|
||||
|
||||
public BufferedImage getOfflineImage() {
|
||||
return offlineImage;
|
||||
}
|
||||
|
||||
public Graphics2D getOfflineGraphics() {
|
||||
return graphics;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
public interface FrameBufferUpdateListener {
|
||||
|
||||
/**
|
||||
* Notify listener, that frame buffer update packet is received, so client is
|
||||
* permitted (but not obligated) to ask server to send another update.
|
||||
*/
|
||||
void frameBufferPacketReceived();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
public interface PaintNotificationListener {
|
||||
|
||||
/**
|
||||
* Notify subscriber that screen is updated, so client can send another frame
|
||||
* buffer update request to server.
|
||||
*/
|
||||
void imagePaintedOnScreen();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public interface RfbConstants {
|
||||
|
||||
public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
|
||||
// public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
|
||||
public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
|
||||
public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
|
||||
|
||||
/**
|
||||
* Server message types.
|
||||
*/
|
||||
final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
|
||||
|
||||
/**
|
||||
* Client message types.
|
||||
*/
|
||||
public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
|
||||
CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
|
||||
|
||||
/**
|
||||
* Server authorization type
|
||||
*/
|
||||
public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
|
||||
|
||||
/**
|
||||
* Server authorization reply.
|
||||
*/
|
||||
public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
|
||||
|
||||
/**
|
||||
* Encodings.
|
||||
*/
|
||||
public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
|
||||
|
||||
/**
|
||||
* Pseudo-encodings.
|
||||
*/
|
||||
public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
|
||||
|
||||
/**
|
||||
* Encodings, which we support.
|
||||
*/
|
||||
public final static int[] SUPPORTED_ENCODINGS_ARRAY = { ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE };
|
||||
|
||||
/**
|
||||
* Frame buffer update request type: update of whole screen or partial update.
|
||||
*/
|
||||
public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
|
||||
|
||||
public static final int KEY_UP = 0, KEY_DOWN = 1;
|
||||
|
||||
public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
|
||||
|
||||
public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
|
||||
|
||||
public static final int PALETTE = 0, TRUE_COLOR = 1;
|
||||
|
||||
/**
|
||||
* Default charset to use when communicating with server.
|
||||
*/
|
||||
public static final Charset CHARSET = Charset.availableCharsets().get("US-ASCII");
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
public class SimpleLogger {
|
||||
|
||||
public static void log(String message) {
|
||||
System.out.println(getPrefix(1) + " LOG: " + message);
|
||||
}
|
||||
|
||||
public static void log(int skipFrames, String message) {
|
||||
System.out.println(getPrefix(1+skipFrames) + " LOG: " + message);
|
||||
}
|
||||
|
||||
public static void debug(String message) {
|
||||
System.out.println(getPrefix(1) + " DEBUG: " + message);
|
||||
}
|
||||
|
||||
public static void info(String message) {
|
||||
System.out.println(getPrefix(1) + " INFO: " + message);
|
||||
}
|
||||
|
||||
public static void warn(String message) {
|
||||
System.err.println(getPrefix(1) + " WARN: " + message);
|
||||
}
|
||||
|
||||
public static void error(String message) {
|
||||
System.err.println(getPrefix(1) + " ERROR: " + message);
|
||||
}
|
||||
|
||||
private static String getPrefix(int skipFrames) {
|
||||
StackTraceElement frame;
|
||||
try {
|
||||
throw new RuntimeException();
|
||||
} catch (Exception e) {
|
||||
frame = e.getStackTrace()[1+skipFrames];
|
||||
}
|
||||
|
||||
return "(" + frame.getFileName() + ":" + frame.getLineNumber() + ") " + frame.getMethodName() + "()";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,350 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.spec.KeySpec;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
|
||||
public class VncClient {
|
||||
|
||||
private Socket socket;
|
||||
private DataInputStream is;
|
||||
private DataOutputStream os;
|
||||
|
||||
private VncScreenDescription screen = new VncScreenDescription();
|
||||
|
||||
private VncClientPacketSender sender;
|
||||
private VncServerPacketReceiver receiver;
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (args.length < 3) {
|
||||
printHelpMessage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
String host = args[0];
|
||||
String port = args[1];
|
||||
String password = args[2];
|
||||
|
||||
try {
|
||||
new VncClient(host, Integer.parseInt(port), password);
|
||||
} catch (NumberFormatException e) {
|
||||
SimpleLogger.error("Incorrect VNC server port number: " + port + ".");
|
||||
System.exit(1);
|
||||
} catch (UnknownHostException e) {
|
||||
SimpleLogger.error("Incorrect VNC server host name: " + host + ".");
|
||||
System.exit(1);
|
||||
} catch (IOException e) {
|
||||
SimpleLogger.error("Cannot communicate with VNC server: " + e.getMessage());
|
||||
System.exit(1);
|
||||
} catch (Throwable e) {
|
||||
SimpleLogger.error("An error happened: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private static void printHelpMessage() {
|
||||
/* LOG */SimpleLogger.info("Usage: HOST PORT PASSWORD.");
|
||||
}
|
||||
|
||||
public VncClient(String host, int port, String password) throws UnknownHostException, IOException {
|
||||
connectTo(host, port, password);
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
sender.closeConnection();
|
||||
receiver.closeConnection();
|
||||
|
||||
try {
|
||||
is.close();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
|
||||
try {
|
||||
os.close();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
|
||||
try {
|
||||
socket.close();
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void connectTo(String host, int port, String password) throws UnknownHostException, IOException {
|
||||
// If port number is too small, then interpret it as display number.
|
||||
if (port < 100)
|
||||
port += 5900;
|
||||
|
||||
// Connect to server
|
||||
SimpleLogger.info("Connecting to VNC server " + host + ":" + port + "...");
|
||||
this.socket = new Socket(host, port);
|
||||
is = new DataInputStream(socket.getInputStream());
|
||||
os = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
// Initialize connection
|
||||
handshake();
|
||||
authenticate(password);
|
||||
initialize();
|
||||
|
||||
// Run client-to-server packet sender
|
||||
sender = new VncClientPacketSender(os, screen, this);
|
||||
|
||||
// Create buffered image canvas
|
||||
BufferedImageCanvas canvas = new BufferedImageCanvas(sender, screen.getFramebufferWidth(), screen.getFramebufferHeight());
|
||||
|
||||
// Subscribe packet sender to various events
|
||||
canvas.addMouseListener(sender);
|
||||
canvas.addMouseMotionListener(sender);
|
||||
canvas.addKeyListener(sender);
|
||||
|
||||
Frame frame = createVncClientMainWindow(canvas, screen.getDesktopName());
|
||||
|
||||
new Thread(sender).start();
|
||||
|
||||
// Run server-to-client packet receiver
|
||||
receiver = new VncServerPacketReceiver(is, canvas, screen, this, sender);
|
||||
try {
|
||||
receiver.run();
|
||||
} finally {
|
||||
frame.setVisible(false);
|
||||
frame.dispose();
|
||||
this.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title) {
|
||||
// Create AWT windows
|
||||
final Frame frame = new Frame(title + " - VNCle");
|
||||
|
||||
// Use scrolling pane to support screens, which are larger than ours
|
||||
ScrollPane scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
|
||||
scroller.add(canvas);
|
||||
scroller.setSize(screen.getFramebufferWidth(), screen.getFramebufferHeight());
|
||||
|
||||
frame.add(scroller);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent evt) {
|
||||
frame.setVisible(false);
|
||||
shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handshake with VNC server.
|
||||
*/
|
||||
private void handshake() throws IOException {
|
||||
|
||||
// Read protocol version
|
||||
byte[] buf = new byte[12];
|
||||
is.readFully(buf);
|
||||
String rfbProtocol = new String(buf);
|
||||
|
||||
// Server should use RFB protocol 3.x
|
||||
if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
|
||||
throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
|
||||
|
||||
// Send response: we support RFB 3.3 only
|
||||
String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
|
||||
os.write(ourProtocolString.getBytes());
|
||||
os.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* VNC authentication.
|
||||
*/
|
||||
private void authenticate(String password) throws IOException {
|
||||
// Read security type
|
||||
int authType = is.readInt();
|
||||
|
||||
switch (authType) {
|
||||
case RfbConstants.CONNECTION_FAILED: {
|
||||
// Server forbids to connect. Read reason and throw exception
|
||||
|
||||
int length = is.readInt();
|
||||
byte[] buf = new byte[length];
|
||||
is.readFully(buf);
|
||||
String reason = new String(buf, RfbConstants.CHARSET);
|
||||
|
||||
throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
|
||||
}
|
||||
|
||||
case RfbConstants.NO_AUTH: {
|
||||
// Client can connect without authorization. Nothing to do.
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.VNC_AUTH: {
|
||||
doVncAuth(password);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode client password and send it to server.
|
||||
*/
|
||||
private void doVncAuth(String password) throws IOException {
|
||||
|
||||
// Read challenge
|
||||
byte[] challenge = new byte[16];
|
||||
is.readFully(challenge);
|
||||
|
||||
// Encode challenge with password
|
||||
byte[] response;
|
||||
try {
|
||||
response = encodePassword(challenge, password);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Send encoded challenge
|
||||
os.write(response);
|
||||
os.flush();
|
||||
|
||||
// Read security result
|
||||
int authResult = is.readInt();
|
||||
|
||||
switch (authResult) {
|
||||
case RfbConstants.VNC_AUTH_OK: {
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.VNC_AUTH_TOO_MANY:
|
||||
throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
|
||||
|
||||
case RfbConstants.VNC_AUTH_FAILED:
|
||||
throw new RuntimeException("Connection to VNC server failed: wrong password.");
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode password using DES encryption with given challenge.
|
||||
*
|
||||
* @param challenge
|
||||
* a random set of bytes.
|
||||
* @param password
|
||||
* a password
|
||||
* @return DES hash of password and challenge
|
||||
*/
|
||||
public byte[] encodePassword(byte[] challenge, String password) throws Exception {
|
||||
// VNC password consist of up to eight ASCII characters.
|
||||
byte[] key = { 0, 0, 0, 0, 0, 0, 0, 0 }; // Padding
|
||||
byte[] passwordAsciiBytes = password.getBytes(RfbConstants.CHARSET);
|
||||
System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
|
||||
|
||||
// Flip bytes (reverse bits) in key
|
||||
for (int i = 0; i < key.length; i++) {
|
||||
key[i] = flipByte(key[i]);
|
||||
}
|
||||
|
||||
KeySpec desKeySpec = new DESKeySpec(key);
|
||||
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
|
||||
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
|
||||
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
|
||||
byte[] response = cipher.doFinal(challenge);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse bits in byte, so least significant bit will be most significant
|
||||
* bit. E.g. 01001100 will become 00110010.
|
||||
*
|
||||
* See also: http://www.vidarholen.net/contents/junk/vnc.html ,
|
||||
* http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
|
||||
*
|
||||
* @param b
|
||||
* a byte
|
||||
* @return byte in reverse order
|
||||
*/
|
||||
private static byte flipByte(byte b) {
|
||||
int b1_8 = (b & 0x1) << 7;
|
||||
int b2_7 = (b & 0x2) << 5;
|
||||
int b3_6 = (b & 0x4) << 3;
|
||||
int b4_5 = (b & 0x8) << 1;
|
||||
int b5_4 = (b & 0x10) >>> 1;
|
||||
int b6_3 = (b & 0x20) >>> 3;
|
||||
int b7_2 = (b & 0x40) >>> 5;
|
||||
int b8_1 = (b & 0x80) >>> 7;
|
||||
byte c = (byte) (b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
|
||||
return c;
|
||||
}
|
||||
|
||||
private void initialize() throws IOException {
|
||||
// Send client initialization message
|
||||
{
|
||||
// Send shared flag
|
||||
os.writeByte(RfbConstants.EXCLUSIVE_ACCESS);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
// Read server initialization message
|
||||
{
|
||||
// Read frame buffer size
|
||||
int framebufferWidth = is.readUnsignedShort();
|
||||
int framebufferHeight = is.readUnsignedShort();
|
||||
screen.setFramebufferSize(framebufferWidth, framebufferHeight);
|
||||
}
|
||||
|
||||
// Read pixel format
|
||||
{
|
||||
int bitsPerPixel = is.readUnsignedByte();
|
||||
int depth = is.readUnsignedByte();
|
||||
|
||||
int bigEndianFlag = is.readUnsignedByte();
|
||||
int trueColorFlag = is.readUnsignedByte();
|
||||
|
||||
int redMax = is.readUnsignedShort();
|
||||
int greenMax = is.readUnsignedShort();
|
||||
int blueMax = is.readUnsignedShort();
|
||||
|
||||
int redShift = is.readUnsignedByte();
|
||||
int greenShift = is.readUnsignedByte();
|
||||
int blueShift = is.readUnsignedByte();
|
||||
|
||||
// Skip padding
|
||||
is.skipBytes(3);
|
||||
|
||||
screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag, trueColorFlag, redMax, greenMax, blueMax, redShift, greenShift, blueShift);
|
||||
}
|
||||
|
||||
// Read desktop name
|
||||
{
|
||||
int length = is.readInt();
|
||||
byte buf[] = new byte[length];
|
||||
is.readFully(buf);
|
||||
String desktopName = new String(buf, RfbConstants.CHARSET);
|
||||
screen.setDesktopName(desktopName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.packet.client.ClientPacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.client.FramebufferUpdateRequestPacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.client.KeyboardEventPacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.client.MouseEventPacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.client.SetEncodingsPacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.client.SetPixelFormatPacket;
|
||||
|
||||
public class VncClientPacketSender implements Runnable, PaintNotificationListener, KeyListener, MouseListener, MouseMotionListener, FrameBufferUpdateListener {
|
||||
|
||||
// Queue for outgoing packets
|
||||
private final BlockingQueue<ClientPacket> queue = new ArrayBlockingQueue<ClientPacket>(30);
|
||||
|
||||
private final DataOutputStream os;
|
||||
private final VncScreenDescription screen;
|
||||
private final VncClient vncConnection;
|
||||
|
||||
private boolean connectionAlive = true;
|
||||
|
||||
// Don't send update request again until we receive next frame buffer update
|
||||
private boolean updateRequestSent = false;
|
||||
|
||||
public VncClientPacketSender(DataOutputStream os, VncScreenDescription screen, VncClient vncConnection) {
|
||||
this.os = os;
|
||||
this.screen = screen;
|
||||
this.vncConnection = vncConnection;
|
||||
|
||||
sendSetPixelFormat();
|
||||
sendSetEncodings();
|
||||
requestFullScreenUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (connectionAlive) {
|
||||
ClientPacket packet = queue.poll(1, TimeUnit.SECONDS);
|
||||
if (packet != null) {
|
||||
packet.write(os);
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (connectionAlive) {
|
||||
closeConnection();
|
||||
vncConnection.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSetEncodings() {
|
||||
queue.add(new SetEncodingsPacket(RfbConstants.SUPPORTED_ENCODINGS_ARRAY));
|
||||
}
|
||||
|
||||
private void sendSetPixelFormat() {
|
||||
if (!screen.isRGB888_32_LE()) {
|
||||
queue.add(new SetPixelFormatPacket(screen, 32, 24, RfbConstants.LITTLE_ENDIAN, RfbConstants.TRUE_COLOR, 255, 255, 255, 16, 8, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void closeConnection() {
|
||||
connectionAlive = false;
|
||||
}
|
||||
|
||||
public void requestFullScreenUpdate() {
|
||||
queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen
|
||||
.getFramebufferHeight()));
|
||||
updateRequestSent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void imagePaintedOnScreen() {
|
||||
if (!updateRequestSent) {
|
||||
queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen
|
||||
.getFramebufferHeight()));
|
||||
updateRequestSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frameBufferPacketReceived() {
|
||||
updateRequestSent = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/**
|
||||
* Current state of buttons 1 to 8 are represented by bits 0 to 7 of
|
||||
* button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
|
||||
* conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
|
||||
* right buttons on the mouse. On a wheel mouse, each step of the wheel
|
||||
* upwards is represented by a press and release of button 4, and each step
|
||||
* downwards is represented by a press and release of button 5.
|
||||
*
|
||||
* @param modifiers
|
||||
* extended modifiers from AWT mouse event
|
||||
* @return VNC mouse button mask
|
||||
*/
|
||||
public static int mapAwtModifiersToVncButtonMask(int modifiers) {
|
||||
int mask = (((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0)
|
||||
| (((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
|
||||
return mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_DOWN, mapAwtKeyToVncKey(e.getKeyCode()));
|
||||
queue.add(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_UP, mapAwtKeyToVncKey(e.getKeyCode()));
|
||||
queue.add(request);
|
||||
}
|
||||
|
||||
private int mapAwtKeyToVncKey(int key) {
|
||||
switch (key) {
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
return 0xff08;
|
||||
case KeyEvent.VK_TAB:
|
||||
return 0xff09;
|
||||
case KeyEvent.VK_ENTER:
|
||||
return 0xff0d;
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
return 0xff1b;
|
||||
case KeyEvent.VK_INSERT:
|
||||
return 0xff63;
|
||||
case KeyEvent.VK_DELETE:
|
||||
return 0xffff;
|
||||
case KeyEvent.VK_HOME:
|
||||
return 0xff50;
|
||||
case KeyEvent.VK_END:
|
||||
return 0xff57;
|
||||
case KeyEvent.VK_PAGE_UP:
|
||||
return 0xff55;
|
||||
case KeyEvent.VK_PAGE_DOWN:
|
||||
return 0xff56;
|
||||
case KeyEvent.VK_LEFT:
|
||||
return 0xff51;
|
||||
case KeyEvent.VK_UP:
|
||||
return 0xff52;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
return 0xff53;
|
||||
case KeyEvent.VK_DOWN:
|
||||
return 0xff54;
|
||||
case KeyEvent.VK_F1:
|
||||
return 0xffbe;
|
||||
case KeyEvent.VK_F2:
|
||||
return 0xffbf;
|
||||
case KeyEvent.VK_F3:
|
||||
return 0xffc0;
|
||||
case KeyEvent.VK_F4:
|
||||
return 0xffc1;
|
||||
case KeyEvent.VK_F5:
|
||||
return 0xffc2;
|
||||
case KeyEvent.VK_F6:
|
||||
return 0xffc3;
|
||||
case KeyEvent.VK_F7:
|
||||
return 0xffc4;
|
||||
case KeyEvent.VK_F8:
|
||||
return 0xffc5;
|
||||
case KeyEvent.VK_F9:
|
||||
return 0xffc6;
|
||||
case KeyEvent.VK_F10:
|
||||
return 0xffc7;
|
||||
case KeyEvent.VK_F11:
|
||||
return 0xffc8;
|
||||
case KeyEvent.VK_F12:
|
||||
return 0xffc9;
|
||||
case KeyEvent.VK_SHIFT:
|
||||
return 0xffe1;
|
||||
case KeyEvent.VK_CONTROL:
|
||||
return 0xffe3;
|
||||
case KeyEvent.VK_META:
|
||||
return 0xffe7;
|
||||
case KeyEvent.VK_ALT:
|
||||
return 0xffe9;
|
||||
case KeyEvent.VK_ALT_GRAPH:
|
||||
return 0xffea;
|
||||
case KeyEvent.VK_BACK_QUOTE:
|
||||
return 0x0060;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
/**
|
||||
* VncScreenDescription - contains information about remote VNC screen.
|
||||
*/
|
||||
public class VncScreenDescription {
|
||||
|
||||
// Frame buffer size
|
||||
private int framebufferWidth = -1;
|
||||
private int framebufferHeight = -1;
|
||||
|
||||
// Desktop name
|
||||
private String desktopName;
|
||||
|
||||
// Bytes per pixel
|
||||
private int bytesPerPixel;
|
||||
|
||||
// Indicates that screen uses format which we want to use:
|
||||
// RGB 24bit packed into 32bit little-endian int.
|
||||
private boolean rgb888_32_le = false;
|
||||
|
||||
public VncScreenDescription() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Store information about server pixel format.
|
||||
*/
|
||||
public void setPixelFormat(int bitsPerPixel, int depth, int bigEndianFlag, int trueColorFlag, int redMax, int greenMax, int blueMax, int redShift,
|
||||
int greenShift, int blueShift) {
|
||||
|
||||
bytesPerPixel = (bitsPerPixel + 7) / 8;
|
||||
|
||||
rgb888_32_le = (depth == 24 && bitsPerPixel == 32 && redShift == 16 && greenShift == 8 && blueShift == 0 && redMax == 255 && greenMax == 255
|
||||
&& blueMax == 255 && bigEndianFlag == RfbConstants.LITTLE_ENDIAN && trueColorFlag == RfbConstants.TRUE_COLOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store information about server screen size.
|
||||
*/
|
||||
public void setFramebufferSize(int framebufferWidth, int framebufferHeight) {
|
||||
this.framebufferWidth = framebufferWidth;
|
||||
this.framebufferHeight = framebufferHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store server desktop name.
|
||||
*/
|
||||
public void setDesktopName(String desktopName) {
|
||||
this.desktopName = desktopName;
|
||||
}
|
||||
|
||||
// Getters for variables, as usual
|
||||
|
||||
public String getDesktopName() {
|
||||
return desktopName;
|
||||
}
|
||||
|
||||
public int getBytesPerPixel() {
|
||||
return bytesPerPixel;
|
||||
}
|
||||
|
||||
public int getFramebufferHeight() {
|
||||
return framebufferHeight;
|
||||
}
|
||||
|
||||
public int getFramebufferWidth() {
|
||||
return framebufferWidth;
|
||||
}
|
||||
|
||||
public boolean isRGB888_32_LE() {
|
||||
return rgb888_32_le;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package com.cloud.consoleproxy.vnc;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.packet.server.FramebufferUpdatePacket;
|
||||
import com.cloud.consoleproxy.vnc.packet.server.ServerCutText;
|
||||
|
||||
public class VncServerPacketReceiver implements Runnable {
|
||||
|
||||
private final VncScreenDescription screen;
|
||||
private BufferedImageCanvas canvas;
|
||||
private DataInputStream is;
|
||||
|
||||
private boolean connectionAlive = true;
|
||||
private VncClient vncConnection;
|
||||
private final FrameBufferUpdateListener fburListener;
|
||||
|
||||
public VncServerPacketReceiver(DataInputStream is, BufferedImageCanvas canvas, VncScreenDescription screen, VncClient vncConnection,
|
||||
FrameBufferUpdateListener fburListener) {
|
||||
this.screen = screen;
|
||||
this.canvas = canvas;
|
||||
this.is = is;
|
||||
this.vncConnection = vncConnection;
|
||||
this.fburListener = fburListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (connectionAlive) {
|
||||
|
||||
// Read server message type
|
||||
int messageType = is.readUnsignedByte();
|
||||
|
||||
// Invoke packet handler by packet type.
|
||||
switch (messageType) {
|
||||
|
||||
case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
|
||||
// Notify sender that frame buffer update is received,
|
||||
// so it can send another frame buffer update request
|
||||
fburListener.frameBufferPacketReceived();
|
||||
// Handle frame buffer update
|
||||
new FramebufferUpdatePacket(canvas, screen, is);
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.SERVER_BELL: {
|
||||
serverBell();
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.SERVER_CUT_TEXT: {
|
||||
serverCutText(is);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unknown server packet type: " + messageType + ".");
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (connectionAlive) {
|
||||
closeConnection();
|
||||
vncConnection.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeConnection() {
|
||||
connectionAlive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle server bell packet.
|
||||
*/
|
||||
private void serverBell() {
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle packet with server clip-board.
|
||||
*/
|
||||
private void serverCutText(DataInputStream is) throws IOException {
|
||||
ServerCutText clipboardContent = new ServerCutText(is);
|
||||
StringSelection contents = new StringSelection(clipboardContent.getContent());
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
|
||||
|
||||
SimpleLogger.info("Server clipboard buffer: "+clipboardContent.getContent());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ClientPacket {
|
||||
|
||||
void write(DataOutputStream os) throws IOException;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
|
||||
/**
|
||||
* FramebufferUpdateRequestPacket
|
||||
*
|
||||
* @author Volodymyr M. Lisivka
|
||||
*/
|
||||
public class FramebufferUpdateRequestPacket implements ClientPacket {
|
||||
|
||||
private final int incremental;
|
||||
private final int x, y, width, height;
|
||||
|
||||
public FramebufferUpdateRequestPacket(int incremental, int x, int y, int width, int height) {
|
||||
this.incremental = incremental;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream os) throws IOException {
|
||||
os.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
|
||||
|
||||
os.writeByte(incremental);
|
||||
os.writeShort(x);
|
||||
os.writeShort(y);
|
||||
os.writeShort(width);
|
||||
os.writeShort(height);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
|
||||
public class KeyboardEventPacket implements ClientPacket {
|
||||
|
||||
private final int downFlag, key;
|
||||
|
||||
public KeyboardEventPacket(int downFlag, int key) {
|
||||
this.downFlag = downFlag;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream os) throws IOException {
|
||||
os.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
|
||||
|
||||
os.writeByte(downFlag);
|
||||
os.writeShort(0); // padding
|
||||
os.writeInt(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
|
||||
public class MouseEventPacket implements ClientPacket {
|
||||
|
||||
private final int buttonMask, x, y;
|
||||
|
||||
public MouseEventPacket(int buttonMask, int x, int y) {
|
||||
this.buttonMask = buttonMask;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream os) throws IOException {
|
||||
os.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
|
||||
|
||||
os.writeByte(buttonMask);
|
||||
os.writeShort(x);
|
||||
os.writeShort(y);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
|
||||
public class SetEncodingsPacket implements ClientPacket {
|
||||
|
||||
private final int[] encodings;
|
||||
|
||||
public SetEncodingsPacket(int[] encodings)
|
||||
{
|
||||
this.encodings = encodings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream os) throws IOException
|
||||
{
|
||||
os.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
|
||||
|
||||
os.writeByte(0);//padding
|
||||
|
||||
os.writeShort(encodings.length);
|
||||
|
||||
for(int i=0;i<encodings.length;i++)
|
||||
{
|
||||
os.writeInt(encodings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.client;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
import com.cloud.consoleproxy.vnc.VncScreenDescription;
|
||||
|
||||
public class SetPixelFormatPacket implements ClientPacket {
|
||||
|
||||
private final int bitsPerPixel, depth, bigEndianFlag, trueColourFlag, redMax, greenMax, blueMax, redShift, greenShift, blueShift;
|
||||
|
||||
private final VncScreenDescription screen;
|
||||
|
||||
public SetPixelFormatPacket(VncScreenDescription screen, int bitsPerPixel, int depth, int bigEndianFlag, int trueColorFlag, int redMax, int greenMax,
|
||||
int blueMax, int redShift, int greenShift, int blueShift) {
|
||||
this.screen = screen;
|
||||
this.bitsPerPixel = bitsPerPixel;
|
||||
this.depth = depth;
|
||||
this.bigEndianFlag = bigEndianFlag;
|
||||
this.trueColourFlag = trueColorFlag;
|
||||
this.redMax = redMax;
|
||||
this.greenMax = greenMax;
|
||||
this.blueMax = blueMax;
|
||||
this.redShift = redShift;
|
||||
this.greenShift = greenShift;
|
||||
this.blueShift = blueShift;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutputStream os) throws IOException {
|
||||
os.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
|
||||
|
||||
// Padding
|
||||
os.writeByte(0);
|
||||
os.writeByte(0);
|
||||
os.writeByte(0);
|
||||
|
||||
// Send pixel format
|
||||
os.writeByte(bitsPerPixel);
|
||||
os.writeByte(depth);
|
||||
os.writeByte(bigEndianFlag);
|
||||
os.writeByte(trueColourFlag);
|
||||
os.writeShort(redMax);
|
||||
os.writeShort(greenMax);
|
||||
os.writeShort(blueMax);
|
||||
os.writeByte(redShift);
|
||||
os.writeByte(greenShift);
|
||||
os.writeByte(blueShift);
|
||||
|
||||
// Padding
|
||||
os.writeByte(0);
|
||||
os.writeByte(0);
|
||||
os.writeByte(0);
|
||||
|
||||
screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag, trueColourFlag, redMax, greenMax, blueMax, redShift, greenShift, blueShift);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
public abstract class AbstractRect implements Rect {
|
||||
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int width;
|
||||
protected final int height;
|
||||
|
||||
public AbstractRect(int x, int y, int width, int height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class CopyRect extends AbstractRect {
|
||||
|
||||
private final int srcX, srcY;
|
||||
|
||||
public CopyRect(int x, int y, int width, int height, DataInputStream is) throws IOException {
|
||||
super(x, y, width, height);
|
||||
|
||||
srcX = is.readUnsignedShort();
|
||||
srcY = is.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(BufferedImage image, Graphics2D graphics) {
|
||||
graphics.copyArea(srcX, srcY, width, height, x - srcX, y - srcY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.BufferedImageCanvas;
|
||||
|
||||
public class FrameBufferSizeChangeRequest extends AbstractRect {
|
||||
|
||||
private final BufferedImageCanvas canvas;
|
||||
|
||||
public FrameBufferSizeChangeRequest(BufferedImageCanvas canvas, int width, int height) {
|
||||
super(0, 0, width, height);
|
||||
this.canvas=canvas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(BufferedImage offlineImage, Graphics2D graphics) {
|
||||
canvas.setCanvasSize(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.BufferedImageCanvas;
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
import com.cloud.consoleproxy.vnc.VncScreenDescription;
|
||||
import com.cloud.consoleproxy.vnc.packet.server.CopyRect;
|
||||
import com.cloud.consoleproxy.vnc.packet.server.RawRect;
|
||||
import com.cloud.consoleproxy.vnc.packet.server.Rect;
|
||||
|
||||
public class FramebufferUpdatePacket {
|
||||
|
||||
private final VncScreenDescription screen;
|
||||
private final BufferedImageCanvas canvas;
|
||||
|
||||
public FramebufferUpdatePacket(BufferedImageCanvas canvas, VncScreenDescription screen, DataInputStream is) throws IOException {
|
||||
this.screen = screen;
|
||||
this.canvas = canvas;
|
||||
readPacketData(is);
|
||||
}
|
||||
|
||||
private void readPacketData(DataInputStream is) throws IOException {
|
||||
is.skipBytes(1);// Skip padding
|
||||
|
||||
// Read number of rectangles
|
||||
int numberOfRectangles = is.readUnsignedShort();
|
||||
|
||||
// For all rectangles
|
||||
for (int i = 0; i < numberOfRectangles; i++) {
|
||||
|
||||
// Read coordinate of rectangle
|
||||
int x = is.readUnsignedShort();
|
||||
int y = is.readUnsignedShort();
|
||||
int width = is.readUnsignedShort();
|
||||
int height = is.readUnsignedShort();
|
||||
|
||||
int encodingType = is.readInt();
|
||||
|
||||
// Process rectangle
|
||||
Rect rect;
|
||||
switch (encodingType) {
|
||||
|
||||
case RfbConstants.ENCODING_RAW: {
|
||||
rect = new RawRect(screen, x, y, width, height, is);
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.ENCODING_COPY_RECT: {
|
||||
rect = new CopyRect(x, y, width, height, is);
|
||||
break;
|
||||
}
|
||||
|
||||
case RfbConstants.ENCODING_DESKTOP_SIZE: {
|
||||
rect = new FrameBufferSizeChangeRequest(canvas, width, height);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unsupported ecnoding: " + encodingType);
|
||||
}
|
||||
|
||||
paint(rect, canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void paint(Rect rect, BufferedImageCanvas canvas) {
|
||||
// Draw rectangle on offline buffer
|
||||
rect.paint(canvas.getOfflineImage(), canvas.getOfflineGraphics());
|
||||
|
||||
// Request update of repainted area
|
||||
canvas.repaint(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.VncScreenDescription;
|
||||
|
||||
public class RawRect extends AbstractRect {
|
||||
private final int[] buf;
|
||||
|
||||
public RawRect(VncScreenDescription screen, int x, int y, int width, int height, DataInputStream is) throws IOException {
|
||||
super(x, y, width, height);
|
||||
|
||||
byte[] bbuf = new byte[width * height * screen.getBytesPerPixel()];
|
||||
is.readFully(bbuf);
|
||||
|
||||
// Convert array of bytes to array of int
|
||||
int size = width * height;
|
||||
buf = new int[size];
|
||||
for (int i = 0, j = 0; i < size; i++, j += 4) {
|
||||
buf[i] = (bbuf[j + 0] & 0xFF) | ((bbuf[j + 1] & 0xFF) << 8) | ((bbuf[j + 2] & 0xFF) << 16) | ((bbuf[j + 3] & 0xFF) << 24);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(BufferedImage image, Graphics2D graphics) {
|
||||
|
||||
DataBuffer dataBuf = image.getRaster().getDataBuffer();
|
||||
|
||||
switch (dataBuf.getDataType()) {
|
||||
|
||||
case DataBuffer.TYPE_INT: {
|
||||
// We chose RGB888 model, so Raster will use DataBufferInt type
|
||||
DataBufferInt dataBuffer = (DataBufferInt) dataBuf;
|
||||
|
||||
int imageWidth = image.getWidth();
|
||||
int imageHeight = image.getHeight();
|
||||
|
||||
// Paint rectangle directly on buffer, line by line
|
||||
int[] imageBuffer = dataBuffer.getData();
|
||||
for (int srcLine = 0, dstLine = y; srcLine < height && dstLine < imageHeight; srcLine++, dstLine++) {
|
||||
try {
|
||||
System.arraycopy(buf, srcLine * width, imageBuffer, x + dstLine * imageWidth, width);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unsupported data buffer in buffered image: expected data buffer of type int (DataBufferInt). Actual data buffer type: "
|
||||
+ dataBuf.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public interface Rect {
|
||||
|
||||
void paint(BufferedImage offlineImage, Graphics2D graphics);
|
||||
|
||||
int getX();
|
||||
int getY();
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.cloud.consoleproxy.vnc.packet.server;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.consoleproxy.vnc.RfbConstants;
|
||||
import com.cloud.consoleproxy.vnc.SimpleLogger;
|
||||
|
||||
public class ServerCutText {
|
||||
|
||||
private String content;
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public ServerCutText(DataInputStream is) throws IOException {
|
||||
readPacketData(is);
|
||||
}
|
||||
|
||||
private void readPacketData(DataInputStream is) throws IOException {
|
||||
is.skipBytes(3);// Skip padding
|
||||
int length = is.readInt();
|
||||
byte buf[] = new byte[length];
|
||||
is.readFully(buf);
|
||||
|
||||
content = new String(buf, RfbConstants.CHARSET);
|
||||
|
||||
/* LOG */SimpleLogger.log("Clippboard content: " + content);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ public class RequestTest extends TestCase {
|
|||
req.logD("Debug for Download");
|
||||
|
||||
|
||||
DownloadAnswer answer = new DownloadAnswer("jobId", 50, "errorString", Status.ABANDONED, "filesystempath", "installpath", 10000000, 20000000);
|
||||
DownloadAnswer answer = new DownloadAnswer("jobId", 50, "errorString", Status.ABANDONED, "filesystempath", "installpath", 10000000, 20000000, "chksum");
|
||||
Response resp = new Response(req, answer);
|
||||
resp.logD("Debug for Download");
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
createNetworkServices(conn);
|
||||
//migrate user concentrated deployment planner choice to new global setting
|
||||
migrateUserConcentratedPlannerChoice(conn);
|
||||
// update domain router table for element it;
|
||||
updateRouters(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -109,8 +111,8 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmtUpdate = null;
|
||||
try {
|
||||
// Load all DataCenters
|
||||
String getNextNetworkSequenceSql = "SELECT value from sequence where name='physical_networks_seq'";
|
||||
String advanceNetworkSequenceSql = "UPDATE sequence set value=value+1 where name='physical_networks_seq'";
|
||||
String getNextNetworkSequenceSql = "SELECT value from `cloud`.`sequence` where name='physical_networks_seq'";
|
||||
String advanceNetworkSequenceSql = "UPDATE `cloud`.`sequence` set value=value+1 where name='physical_networks_seq'";
|
||||
|
||||
String xenPublicLabel = getNetworkLabelFromConfig(conn, "xen.public.network.device");
|
||||
String xenPrivateLabel = getNetworkLabelFromConfig(conn, "xen.private.network.device");
|
||||
|
|
@ -125,7 +127,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
String vmwarePrivateLabel = getNetworkLabelFromConfig(conn, "vmware.private.vswitch");
|
||||
String vmwareGuestLabel = getNetworkLabelFromConfig(conn, "vmware.guest.vswitch");
|
||||
|
||||
pstmt = conn.prepareStatement("SELECT id, domain_id, networktype, vnet, name FROM data_center");
|
||||
pstmt = conn.prepareStatement("SELECT id, domain_id, networktype, vnet, name FROM `cloud`.`data_center`");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long zoneId = rs.getLong(1);
|
||||
|
|
@ -215,7 +217,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
|
||||
// add physical network service provider - VirtualRouter
|
||||
s_logger.debug("Adding PhysicalNetworkServiceProvider VirtualRouter");
|
||||
String insertPNSP = "INSERT INTO `physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," +
|
||||
String insertPNSP = "INSERT INTO `cloud`.`physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," +
|
||||
"`destination_physical_network_id`, `vpn_service_provided`, `dhcp_service_provided`, `dns_service_provided`, `gateway_service_provided`," +
|
||||
"`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," +
|
||||
"`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
|
|
@ -241,7 +243,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
pstmtUpdate.close();
|
||||
|
||||
// add virtual_router_element
|
||||
String fetchNSPid = "SELECT id from physical_network_service_providers where physical_network_id=" + physicalNetworkId;
|
||||
String fetchNSPid = "SELECT id from `cloud`.`physical_network_service_providers` where physical_network_id=" + physicalNetworkId;
|
||||
pstmt2 = conn.prepareStatement(fetchNSPid);
|
||||
ResultSet rsNSPid = pstmt2.executeQuery();
|
||||
rsNSPid.next();
|
||||
|
|
@ -249,7 +251,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
rsSeq.close();
|
||||
pstmt2.close();
|
||||
|
||||
String insertRouter = "INSERT INTO `virtual_router_providers` (`nsp_id`, `uuid` , `type` , `enabled`) " +
|
||||
String insertRouter = "INSERT INTO `cloud`.`virtual_router_providers` (`nsp_id`, `uuid` , `type` , `enabled`) " +
|
||||
"VALUES (?,?,?,?)";
|
||||
pstmtUpdate = conn.prepareStatement(insertRouter);
|
||||
pstmtUpdate.setLong(1, nspId);
|
||||
|
|
@ -261,28 +263,28 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
|
||||
// add physicalNetworkId to op_dc_vnet_alloc for this zone
|
||||
s_logger.debug("Adding PhysicalNetwork to op_dc_vnet_alloc");
|
||||
String updateVnet = "UPDATE op_dc_vnet_alloc SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
String updateVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
pstmtUpdate = conn.prepareStatement(updateVnet);
|
||||
pstmtUpdate.executeUpdate();
|
||||
pstmtUpdate.close();
|
||||
|
||||
// add physicalNetworkId to vlan for this zone
|
||||
s_logger.debug("Adding PhysicalNetwork to VLAN");
|
||||
String updateVLAN = "UPDATE vlan SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
String updateVLAN = "UPDATE `cloud`.`vlan` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
pstmtUpdate = conn.prepareStatement(updateVLAN);
|
||||
pstmtUpdate.executeUpdate();
|
||||
pstmtUpdate.close();
|
||||
|
||||
// add physicalNetworkId to user_ip_address for this zone
|
||||
s_logger.debug("Adding PhysicalNetwork to user_ip_address");
|
||||
String updateUsrIp = "UPDATE user_ip_address SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
String updateUsrIp = "UPDATE `cloud`.`user_ip_address` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
|
||||
pstmtUpdate = conn.prepareStatement(updateUsrIp);
|
||||
pstmtUpdate.executeUpdate();
|
||||
pstmtUpdate.close();
|
||||
|
||||
// add physicalNetworkId to guest networks for this zone
|
||||
s_logger.debug("Adding PhysicalNetwork to networks");
|
||||
String updateNet = "UPDATE networks SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId + " AND traffic_type = 'Guest'";
|
||||
String updateNet = "UPDATE `cloud`.`networks` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId + " AND traffic_type = 'Guest'";
|
||||
pstmtUpdate = conn.prepareStatement(updateNet);
|
||||
pstmtUpdate.executeUpdate();
|
||||
pstmtUpdate.close();
|
||||
|
|
@ -314,7 +316,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
}
|
||||
|
||||
private String getNetworkLabelFromConfig(Connection conn, String name){
|
||||
String sql = "SELECT value FROM configuration where name = '"+name+"'";
|
||||
String sql = "SELECT value FROM `cloud`.`configuration` where name = '"+name+"'";
|
||||
String networkLabel = null;
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
|
|
@ -354,7 +356,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select name, value from configuration where category in ('Hidden', 'Secure')");
|
||||
pstmt = conn.prepareStatement("select name, value from `cloud`.`configuration` where category in ('Hidden', 'Secure')");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
String name = rs.getString(1);
|
||||
|
|
@ -363,7 +365,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
continue;
|
||||
}
|
||||
String encryptedValue = DBEncryptionUtil.encrypt(value);
|
||||
pstmt = conn.prepareStatement("update configuration set value=? where name=?");
|
||||
pstmt = conn.prepareStatement("update `cloud`.`configuration` set value=? where name=?");
|
||||
pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
|
||||
pstmt.setString(2, name);
|
||||
pstmt.executeUpdate();
|
||||
|
|
@ -390,7 +392,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select id, value from host_details where name = 'password'");
|
||||
pstmt = conn.prepareStatement("select id, value from `cloud`.`host_details` where name = 'password'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
|
|
@ -399,7 +401,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
continue;
|
||||
}
|
||||
String encryptedValue = DBEncryptionUtil.encrypt(value);
|
||||
pstmt = conn.prepareStatement("update host_details set value=? where id=?");
|
||||
pstmt = conn.prepareStatement("update `cloud`.`host_details` set value=? where id=?");
|
||||
pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
|
||||
pstmt.setLong(2, id);
|
||||
pstmt.executeUpdate();
|
||||
|
|
@ -426,7 +428,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select id, vnc_password from vm_instance");
|
||||
pstmt = conn.prepareStatement("select id, vnc_password from `cloud`.`vm_instance`");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
|
|
@ -435,7 +437,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
continue;
|
||||
}
|
||||
String encryptedValue = DBEncryptionUtil.encrypt(value);
|
||||
pstmt = conn.prepareStatement("update vm_instance set vnc_password=? where id=?");
|
||||
pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vnc_password=? where id=?");
|
||||
pstmt.setBytes(1, encryptedValue.getBytes("UTF-8"));
|
||||
pstmt.setLong(2, id);
|
||||
pstmt.executeUpdate();
|
||||
|
|
@ -462,13 +464,13 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select id, secret_key from user");
|
||||
pstmt = conn.prepareStatement("select id, secret_key from `cloud`.`user`");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
String secretKey = rs.getString(2);
|
||||
String encryptedSecretKey = DBEncryptionUtil.encrypt(secretKey);
|
||||
pstmt = conn.prepareStatement("update user set secret_key=? where id=?");
|
||||
pstmt = conn.prepareStatement("update `cloud`.`user` set secret_key=? where id=?");
|
||||
if (encryptedSecretKey == null) {
|
||||
pstmt.setNull(1, Types.VARCHAR);
|
||||
} else {
|
||||
|
|
@ -503,7 +505,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
uniqueKeys.put("secondary_storage_vm", keys);
|
||||
|
||||
// drop keys
|
||||
s_logger.debug("Dropping public_ip_address keys from secondary_storage_vm and console_proxy tables...");
|
||||
s_logger.debug("Dropping public_ip_address keys from `cloud`.`secondary_storage_vm` and console_proxy tables...");
|
||||
for (String tableName : uniqueKeys.keySet()) {
|
||||
DbUpgradeUtils.dropKeysIfExist(conn, tableName, uniqueKeys.get(tableName), true);
|
||||
}
|
||||
|
|
@ -514,7 +516,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn
|
||||
.prepareStatement("select id, dns_service, gateway_service, firewall_service, lb_service, userdata_service, vpn_service, dhcp_service, unique_name from network_offerings where traffic_type='Guest'");
|
||||
.prepareStatement("select id, dns_service, gateway_service, firewall_service, lb_service, userdata_service, vpn_service, dhcp_service, unique_name from `cloud`.`network_offerings` where traffic_type='Guest'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
|
|
@ -560,7 +562,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
}
|
||||
|
||||
for (String service : services) {
|
||||
pstmt = conn.prepareStatement("INSERT INTO ntwk_offering_service_map (`network_offering_id`, `service`, `provider`, `created`) values (?,?,?, now())");
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ntwk_offering_service_map` (`network_offering_id`, `service`, `provider`, `created`) values (?,?,?, now())");
|
||||
pstmt.setLong(1, id);
|
||||
pstmt.setString(2, service);
|
||||
if (service.equalsIgnoreCase("SecurityGroup")) {
|
||||
|
|
@ -592,22 +594,22 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
ResultSet rs = null;
|
||||
try {
|
||||
// update subdomain access field for existing domain specific networks
|
||||
pstmt = conn.prepareStatement("select value from configuration where name='allow.subdomain.network.access'");
|
||||
pstmt = conn.prepareStatement("select value from `cloud`.`configuration` where name='allow.subdomain.network.access'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
boolean subdomainAccess = Boolean.valueOf(rs.getString(1));
|
||||
pstmt = conn.prepareStatement("UPDATE domain_network_ref SET subdomain_access=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`domain_network_ref` SET subdomain_access=?");
|
||||
pstmt.setBoolean(1, subdomainAccess);
|
||||
pstmt.executeUpdate();
|
||||
s_logger.debug("Successfully updated subdomain_access field in network_domain table with value " + subdomainAccess);
|
||||
}
|
||||
|
||||
// convert zone level 2.2.x networks to ROOT domain 3.0 access networks
|
||||
pstmt = conn.prepareStatement("select id from networks where shared=true and is_domain_specific=false and traffic_type='Guest'");
|
||||
pstmt = conn.prepareStatement("select id from `cloud`.`networks` where shared=true and is_domain_specific=false and traffic_type='Guest'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long networkId = rs.getLong(1);
|
||||
pstmt = conn.prepareStatement("INSERT INTO domain_network_ref (domain_id, network_id, subdomain_access) VALUES (1, ?, 1)");
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`domain_network_ref` (domain_id, network_id, subdomain_access) VALUES (1, ?, 1)");
|
||||
pstmt.setLong(1, networkId);
|
||||
pstmt.executeUpdate();
|
||||
s_logger.debug("Successfully converted zone specific network id=" + networkId + " to the ROOT domain level network with subdomain access set to true");
|
||||
|
|
@ -634,18 +636,18 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
ResultSet rs = null;
|
||||
ResultSet rs1 = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select id, network_offering_id from networks where traffic_type='Guest'");
|
||||
pstmt = conn.prepareStatement("select id, network_offering_id from `cloud`.`networks` where traffic_type='Guest'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long networkId = rs.getLong(1);
|
||||
long networkOfferingId = rs.getLong(2);
|
||||
pstmt = conn.prepareStatement("select service, provider from ntwk_offering_service_map where network_offering_id=?");
|
||||
pstmt = conn.prepareStatement("select service, provider from `cloud`.`ntwk_offering_service_map` where network_offering_id=?");
|
||||
pstmt.setLong(1, networkOfferingId);
|
||||
rs1 = pstmt.executeQuery();
|
||||
while (rs1.next()) {
|
||||
String service = rs1.getString(1);
|
||||
String provider = rs1.getString(2);
|
||||
pstmt = conn.prepareStatement("INSERT INTO ntwk_service_map (`network_id`, `service`, `provider`, `created`) values (?,?,?, now())");
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`ntwk_service_map` (`network_id`, `service`, `provider`, `created`) values (?,?,?, now())");
|
||||
pstmt.setLong(1, networkId);
|
||||
pstmt.setString(2, service);
|
||||
pstmt.setString(3, provider);
|
||||
|
|
@ -672,6 +674,26 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateRouters(Connection conn) {
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
s_logger.debug("Updating domain_router table");
|
||||
pstmt = conn
|
||||
.prepareStatement("UPDATE domain_router, virtual_router_providers vrp LEFT JOIN (physical_network_service_providers pnsp INNER JOIN networks ntwk INNER JOIN domain_router vr) ON (vrp.nsp_id = pnsp.id and pnsp.physical_network_id = ntwk.physical_network_id and ntwk.id=vr.network_id) SET vr.element_id=vrp.id;");
|
||||
pstmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to update router table. ", e);
|
||||
} finally {
|
||||
try {
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to close statement for router table. ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateReduntantRouters(Connection conn) {
|
||||
PreparedStatement pstmt = null;
|
||||
|
|
@ -680,9 +702,9 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
try {
|
||||
// get all networks that need to be updated to the redundant network offerings
|
||||
pstmt = conn
|
||||
.prepareStatement("select ni.network_id, n.network_offering_id from nics ni, networks n where ni.instance_id in (select id from domain_router where is_redundant_router=1) and n.id=ni.network_id and n.traffic_type='Guest'");
|
||||
.prepareStatement("select ni.network_id, n.network_offering_id from `cloud`.`nics` ni, `cloud`.`networks` n where ni.instance_id in (select id from `cloud`.`domain_router` where is_redundant_router=1) and n.id=ni.network_id and n.traffic_type='Guest'");
|
||||
rs = pstmt.executeQuery();
|
||||
pstmt = conn.prepareStatement("select count(*) from network_offerings");
|
||||
pstmt = conn.prepareStatement("select count(*) from `cloud`.`network_offerings`");
|
||||
rs1 = pstmt.executeQuery();
|
||||
long ntwkOffCount = 0;
|
||||
while (rs1.next()) {
|
||||
|
|
@ -690,7 +712,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
}
|
||||
|
||||
s_logger.debug("Have " + ntwkOffCount + " networkOfferings");
|
||||
pstmt = conn.prepareStatement("CREATE TEMPORARY TABLE network_offerings2 ENGINE=MEMORY SELECT * FROM network_offerings WHERE id=1");
|
||||
pstmt = conn.prepareStatement("CREATE TEMPORARY TABLE `cloud`.`network_offerings2` ENGINE=MEMORY SELECT * FROM `cloud`.`network_offerings` WHERE id=1");
|
||||
pstmt.executeUpdate();
|
||||
|
||||
HashMap<Long, Long> newNetworkOfferingMap = new HashMap<Long, Long>();
|
||||
|
|
@ -703,11 +725,11 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
|
||||
if (!newNetworkOfferingMap.containsKey(networkOfferingId)) {
|
||||
// clone the record to
|
||||
pstmt = conn.prepareStatement("INSERT INTO network_offerings2 SELECT * FROM network_offerings WHERE id=?");
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings2` SELECT * FROM `cloud`.`network_offerings` WHERE id=?");
|
||||
pstmt.setLong(1, networkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("SELECT unique_name FROM network_offerings WHERE id=?");
|
||||
pstmt = conn.prepareStatement("SELECT unique_name FROM `cloud`.`network_offerings` WHERE id=?");
|
||||
pstmt.setLong(1, networkOfferingId);
|
||||
rs1 = pstmt.executeQuery();
|
||||
String uniqueName = null;
|
||||
|
|
@ -715,7 +737,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
uniqueName = rs1.getString(1) + "-redundant";
|
||||
}
|
||||
|
||||
pstmt = conn.prepareStatement("UPDATE network_offerings2 SET id=?, redundant_router_service=1, unique_name=?, name=? WHERE id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings2` SET id=?, redundant_router_service=1, unique_name=?, name=? WHERE id=?");
|
||||
ntwkOffCount = ntwkOffCount + 1;
|
||||
newNetworkOfferingId = ntwkOffCount;
|
||||
pstmt.setLong(1, newNetworkOfferingId);
|
||||
|
|
@ -724,17 +746,17 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
pstmt.setLong(4, networkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("INSERT INTO network_offerings SELECT * from network_offerings2 WHERE id=" + newNetworkOfferingId);
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings` SELECT * from `cloud`.`network_offerings2` WHERE id=" + newNetworkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("UPDATE networks SET network_offering_id=? where id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
|
||||
pstmt.setLong(1, newNetworkOfferingId);
|
||||
pstmt.setLong(2, networkId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
newNetworkOfferingMap.put(networkOfferingId, ntwkOffCount);
|
||||
} else {
|
||||
pstmt = conn.prepareStatement("UPDATE networks SET network_offering_id=? where id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
|
||||
newNetworkOfferingId = newNetworkOfferingMap.get(networkOfferingId);
|
||||
pstmt.setLong(1, newNetworkOfferingId);
|
||||
pstmt.setLong(2, networkId);
|
||||
|
|
@ -748,7 +770,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
throw new CloudRuntimeException("Unable to update redundant router networks", e);
|
||||
} finally {
|
||||
try {
|
||||
pstmt = conn.prepareStatement("DROP TABLE network_offerings2");
|
||||
pstmt = conn.prepareStatement("DROP TABLE `cloud`.`network_offerings2`");
|
||||
pstmt.executeUpdate();
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
|
|
@ -773,9 +795,9 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
try {
|
||||
// get all networks that need to be updated to the redundant network offerings
|
||||
pstmt = conn
|
||||
.prepareStatement("select id, network_offering_id from networks where switch_to_isolated=1");
|
||||
.prepareStatement("select id, network_offering_id from `cloud`.`networks` where switch_to_isolated=1");
|
||||
rs = pstmt.executeQuery();
|
||||
pstmt = conn.prepareStatement("select count(*) from network_offerings");
|
||||
pstmt = conn.prepareStatement("select count(*) from `cloud`.`network_offerings`");
|
||||
rs1 = pstmt.executeQuery();
|
||||
long ntwkOffCount = 0;
|
||||
while (rs1.next()) {
|
||||
|
|
@ -783,7 +805,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
}
|
||||
|
||||
s_logger.debug("Have " + ntwkOffCount + " networkOfferings");
|
||||
pstmt = conn.prepareStatement("CREATE TEMPORARY TABLE network_offerings2 ENGINE=MEMORY SELECT * FROM network_offerings WHERE id=1");
|
||||
pstmt = conn.prepareStatement("CREATE TEMPORARY TABLE `cloud`.`network_offerings2` ENGINE=MEMORY SELECT * FROM `cloud`.`network_offerings` WHERE id=1");
|
||||
pstmt.executeUpdate();
|
||||
|
||||
HashMap<Long, Long> newNetworkOfferingMap = new HashMap<Long, Long>();
|
||||
|
|
@ -796,11 +818,11 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
|
||||
if (!newNetworkOfferingMap.containsKey(networkOfferingId)) {
|
||||
// clone the record to
|
||||
pstmt = conn.prepareStatement("INSERT INTO network_offerings2 SELECT * FROM network_offerings WHERE id=?");
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings2` SELECT * FROM `cloud`.`network_offerings` WHERE id=?");
|
||||
pstmt.setLong(1, networkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("UPDATE network_offerings2 SET id=?, guest_type='Isolated', unique_name=?, name=? WHERE id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings2` SET id=?, guest_type='Isolated', unique_name=?, name=? WHERE id=?");
|
||||
ntwkOffCount = ntwkOffCount + 1;
|
||||
newNetworkOfferingId = ntwkOffCount;
|
||||
String uniqueName = "Isolated w/o source nat";
|
||||
|
|
@ -810,17 +832,17 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
pstmt.setLong(4, networkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("INSERT INTO network_offerings SELECT * from network_offerings2 WHERE id=" + newNetworkOfferingId);
|
||||
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`network_offerings` SELECT * from `cloud`.`network_offerings2` WHERE id=" + newNetworkOfferingId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("UPDATE networks SET network_offering_id=? where id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
|
||||
pstmt.setLong(1, newNetworkOfferingId);
|
||||
pstmt.setLong(2, networkId);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
newNetworkOfferingMap.put(networkOfferingId, ntwkOffCount);
|
||||
} else {
|
||||
pstmt = conn.prepareStatement("UPDATE networks SET network_offering_id=? where id=?");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`networks` SET network_offering_id=? where id=?");
|
||||
newNetworkOfferingId = newNetworkOfferingMap.get(networkOfferingId);
|
||||
pstmt.setLong(1, newNetworkOfferingId);
|
||||
pstmt.setLong(2, networkId);
|
||||
|
|
@ -841,18 +863,12 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
throw new CloudRuntimeException("Unable to switch networks to isolated", e);
|
||||
} finally {
|
||||
try {
|
||||
pstmt = conn.prepareStatement("DROP TABLE network_offerings2");
|
||||
pstmt.executeUpdate();
|
||||
pstmt = conn.prepareStatement("DROP TABLE network_offerings2");
|
||||
pstmt = conn.prepareStatement("DROP TABLE `cloud`.`network_offerings2`");
|
||||
pstmt.executeUpdate();
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
|
||||
if (rs1 != null) {
|
||||
rs1.close();
|
||||
}
|
||||
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
|
|
@ -865,7 +881,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = conn.prepareStatement("SELECT value FROM configuration where name = 'use.user.concentrated.pod.allocation'");
|
||||
pstmt = conn.prepareStatement("SELECT value FROM `cloud`.`configuration` where name = 'use.user.concentrated.pod.allocation'");
|
||||
rs = pstmt.executeQuery();
|
||||
Boolean isuserconcentrated = false;
|
||||
if(rs.next()) {
|
||||
|
|
@ -877,7 +893,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
|
||||
if(isuserconcentrated){
|
||||
String currentAllocationAlgo = "random";
|
||||
pstmt = conn.prepareStatement("SELECT value FROM configuration where name = 'vm.allocation.algorithm'");
|
||||
pstmt = conn.prepareStatement("SELECT value FROM `cloud`.`configuration` where name = 'vm.allocation.algorithm'");
|
||||
rs = pstmt.executeQuery();
|
||||
if(rs.next()) {
|
||||
currentAllocationAlgo = rs.getString(1);
|
||||
|
|
@ -892,7 +908,7 @@ public class Upgrade2214to30 implements DbUpgrade {
|
|||
newAllocAlgo = "userconcentratedpod_firstfit";
|
||||
}
|
||||
|
||||
pstmt = conn.prepareStatement("UPDATE configuration SET value = ? WHERE name = 'vm.allocation.algorithm'");
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` SET value = ? WHERE name = 'vm.allocation.algorithm'");
|
||||
pstmt.setString(1, newAllocAlgo);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -51,13 +51,10 @@ public class Test2214To30DBUpgrade extends TestCase {
|
|||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
public void test2213to30Upgrade() throws SQLException {
|
||||
public void test2214to30Upgrade() throws SQLException {
|
||||
s_logger.debug("Finding sample data from 2.2.14");
|
||||
DbTestUtils.executeScript(
|
||||
"PreviousDatabaseSchema/2.2.14/cloud_usage_2214.sql", false,
|
||||
true);
|
||||
DbTestUtils.executeScript(
|
||||
"PreviousDatabaseSchema/2.2.14/advance_zone_2.2.14.sql", false,
|
||||
"PreviousDatabaseSchema/2.2.14/alena_2214.sql", false,
|
||||
true);
|
||||
|
||||
DatabaseUpgradeChecker checker = ComponentLocator
|
||||
|
|
@ -77,14 +74,13 @@ public class Test2214To30DBUpgrade extends TestCase {
|
|||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void checkPhysicalNetworks(Connection conn) throws SQLException {
|
||||
PreparedStatement pstmt;
|
||||
|
||||
pstmt = conn
|
||||
.prepareStatement("SELECT version FROM version ORDER BY id DESC LIMIT 1");
|
||||
.prepareStatement("SELECT version FROM `cloud`.`version` ORDER BY id DESC LIMIT 1");
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
assert rs.next() : "No version selected";
|
||||
assert rs.getString(1).equals("3.0.0") : "VERSION stored is not 3.0.0: "
|
||||
|
|
@ -92,7 +88,7 @@ public class Test2214To30DBUpgrade extends TestCase {
|
|||
rs.close();
|
||||
pstmt.close();
|
||||
|
||||
pstmt = conn.prepareStatement("SELECT COUNT(*) FROM physical_network");
|
||||
pstmt = conn.prepareStatement("SELECT COUNT(*) FROM `cloud`.`physical_network`");
|
||||
rs = pstmt.executeQuery();
|
||||
assert rs.next() : "No physical networks setup.";
|
||||
rs.close();
|
||||
|
|
@ -133,7 +129,7 @@ public class Test2214To30DBUpgrade extends TestCase {
|
|||
PreparedStatement pstmt;
|
||||
for (String field : fields) {
|
||||
pstmt = conn
|
||||
.prepareStatement("SHOW COLUMNS FROM network_offerings LIKE ?");
|
||||
.prepareStatement("SHOW COLUMNS FROM `cloud`.`network_offerings` LIKE ?");
|
||||
pstmt.setString(1, field);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (!rs.next()) {
|
||||
|
|
@ -183,11 +179,10 @@ public class Test2214To30DBUpgrade extends TestCase {
|
|||
fields.add("restart_required");
|
||||
fields.add("specify_ip_ranges");
|
||||
fields.add("acl_type");
|
||||
fields.add("specified_cidr");
|
||||
|
||||
PreparedStatement pstmt;
|
||||
for (String field : fields) {
|
||||
pstmt = conn.prepareStatement("SHOW COLUMNS FROM networks LIKE ?");
|
||||
pstmt = conn.prepareStatement("SHOW COLUMNS FROM `cloud`.`networks` LIKE ?");
|
||||
pstmt.setString(1, field);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if (!rs.next()) {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
--;
|
||||
-- Schema upgrade from 2.2.14 to 3.0;
|
||||
--;
|
||||
|
||||
|
||||
#Schema upgrade from 2.2.14 to 3.0;
|
||||
|
||||
ALTER TABLE `cloud`.`host` ADD COLUMN `hypervisor_version` varchar(32) COMMENT 'hypervisor version' AFTER hypervisor_type;
|
||||
|
||||
|
|
@ -266,15 +266,6 @@ ALTER TABLE `cloud`.`guest_os_category` ADD CONSTRAINT `uc_guest_os_category__uu
|
|||
ALTER TABLE `cloud`.`nics` ADD COLUMN `uuid` varchar(40);
|
||||
ALTER TABLE `cloud`.`nics` ADD CONSTRAINT `uc_nics__uuid` UNIQUE (`uuid`);
|
||||
|
||||
CREATE TABLE `cloud`.`vm_template_details` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`template_id` bigint unsigned NOT NULL COMMENT 'template id',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`value` varchar(1024) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_vm_template_details__template_id` FOREIGN KEY `fk_vm_template_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud`.`op_host_capacity` ADD COLUMN `created` datetime;
|
||||
ALTER TABLE `cloud`.`op_host_capacity` ADD COLUMN `update_time` datetime;
|
||||
|
||||
|
|
@ -334,7 +325,7 @@ ALTER TABLE `cloud`.`service_offering` ADD COLUMN `sort_key` int(32) NOT NULL de
|
|||
--NAAS;
|
||||
--;
|
||||
|
||||
CREATE TABLE `ntwk_service_map` (
|
||||
CREATE TABLE `cloud`.`ntwk_service_map` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`network_id` bigint unsigned NOT NULL COMMENT 'network_id',
|
||||
`service` varchar(255) NOT NULL COMMENT 'service',
|
||||
|
|
@ -494,6 +485,8 @@ CREATE TABLE `cloud`.`virtual_router_providers` (
|
|||
CONSTRAINT `uc_virtual_router_providers__uuid` UNIQUE (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud`.`domain_router` ADD COLUMN `element_id` bigint unsigned NOT NULL COMMENT 'correlated virtual router provider ID' AFTER id;
|
||||
ALTER TABLE `cloud`.`domain_router` ADD CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`);
|
||||
|
||||
INSERT INTO `cloud`.`sequence` (name, value) VALUES ('physical_networks_seq', 200);
|
||||
ALTER TABLE `cloud`.`networks` ADD COLUMN `physical_network_id` bigint unsigned COMMENT 'physical network id that this configuration is based on' AFTER network_offering_id;
|
||||
|
|
@ -568,14 +561,14 @@ insert into `cloud`.`network_offerings` (`name`, `unique_name`, `display_text`,
|
|||
UPDATE `cloud`.`network_offerings` set specify_ip_ranges=1 where name in ('System-Public-Network', 'System-Storage-Network', 'DefaultSharedNetworkOfferingWithSGService', 'DefaultSharedNetworkOffering', 'DefaultIsolatedNetworkOffering');
|
||||
|
||||
|
||||
CREATE TABLE `ntwk_offering_service_map` (
|
||||
CREATE TABLE `cloud`.`ntwk_offering_service_map` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`network_offering_id` bigint unsigned NOT NULL COMMENT 'network_offering_id',
|
||||
`service` varchar(255) NOT NULL COMMENT 'service',
|
||||
`provider` varchar(255) COMMENT 'service provider',
|
||||
`created` datetime COMMENT 'date created',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_ntwk_offering_service_map__network_offering_id` FOREIGN KEY(`network_offering_id`) REFERENCES `network_offerings`(`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_ntwk_offering_service_map__network_offering_id` FOREIGN KEY(`network_offering_id`) REFERENCES `cloud`.`network_offerings`(`id`) ON DELETE CASCADE,
|
||||
UNIQUE (`network_offering_id`, `service`, `provider`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
|
@ -623,7 +616,7 @@ UPDATE `cloud`.`networks` SET acl_type='Domain' where guest_type is not null and
|
|||
UPDATE `cloud`.`networks` SET acl_type='Account' where guest_type='Virtual';
|
||||
UPDATE `cloud`.`networks` SET acl_type='Account' where guest_type='Direct' and shared=0;
|
||||
ALTER TABLE `cloud`.`domain_network_ref` ADD COLUMN `subdomain_access` int(1) unsigned COMMENT '1 if network can be accessible from the subdomain';
|
||||
UPDATE `cloud`.`networks` SET specify_ip_ranges=(SELECT specify_ip_ranges FROM network_offerings no where no.id=network_offering_id);
|
||||
UPDATE `cloud`.`networks` SET specify_ip_ranges=(SELECT specify_ip_ranges FROM `cloud`.`network_offerings` no where no.id=network_offering_id);
|
||||
|
||||
|
||||
DELETE FROM `cloud`.`configuration` WHERE name='network.redundantrouter';
|
||||
|
|
@ -649,6 +642,25 @@ UPDATE `cloud`.`configuration` SET category = 'Hidden' WHERE name = 'kvm.guest.n
|
|||
ALTER TABLE `cloud`.`physical_network_traffic_types` ADD COLUMN `ovm_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a Ovm host';
|
||||
ALTER TABLE `cloud`.`dc_storage_network_ip_range` ADD COLUMN `gateway` varchar(15) NOT NULL COMMENT 'gateway ip address';
|
||||
|
||||
ALTER TABLE `cloud`.`volumes` ADD COLUMN `last_pool_id` bigint unsigned;
|
||||
UPDATE `cloud`.`volumes` SET `last_pool_id` = `pool_id`;
|
||||
|
||||
ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN `is_system` int(1) unsigned NOT NULL default '0';
|
||||
ALTER TABLE `cloud`.`volumes` ADD COLUMN `update_count` bigint unsigned NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `cloud`.`volumes` ADD INDEX `i_volumes__update_count`(`update_count`);
|
||||
ALTER TABLE `cloud`.`firewall_rules` ADD COLUMN `type` varchar(10) NOT NULL DEFAULT 'USER';
|
||||
|
||||
CREATE TABLE `cloud`.`account_details` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`account_id` bigint unsigned NOT NULL COMMENT 'account id',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`value` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_account_details__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP TABLE IF EXISTS `cloud_usage`.`usage_security_group`;
|
||||
|
||||
CREATE TABLE `cloud_usage`.`usage_security_group` (
|
||||
`zone_id` bigint unsigned NOT NULL,
|
||||
`account_id` bigint unsigned NOT NULL,
|
||||
|
|
|
|||
|
|
@ -7,21 +7,30 @@ from functools import partial
|
|||
import os
|
||||
import sys
|
||||
import logging
|
||||
|
||||
module_logger = "testclient.testcase"
|
||||
|
||||
def testCaseLogger(message, logger=None):
|
||||
if logger is not None:
|
||||
logger.debug(message)
|
||||
|
||||
class TestCaseExecuteEngine(object):
|
||||
def __init__(self, testclient, testCaseFolder, testcaseLogFile=None, testResultLogFile=None):
|
||||
self.testclient = testclient
|
||||
self.testCaseFolder = testCaseFolder
|
||||
self.logger = None
|
||||
if testcaseLogFile is not None:
|
||||
logger = logging.getLogger("testcase")
|
||||
logger = logging.getLogger("testclient.testcase.TestCaseExecuteEngine")
|
||||
fh = logging.FileHandler(testcaseLogFile)
|
||||
fh.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s"))
|
||||
logger.addHandler(fh)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
self.logger = logger
|
||||
if testResultLogFile is not None:
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.ERROR)
|
||||
ch.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s"))
|
||||
self.logger.addHandler(ch)
|
||||
fp = open(testResultLogFile, "w")
|
||||
self.testResultLogFile = fp
|
||||
else:
|
||||
|
|
@ -40,5 +49,3 @@ class TestCaseExecuteEngine(object):
|
|||
self.injectTestCase(suite)
|
||||
|
||||
unittest.TextTestRunner(stream=self.testResultLogFile, verbosity=2).run(suite)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import httplib
|
||||
import urllib2
|
||||
import urllib
|
||||
import base64
|
||||
import hmac
|
||||
|
|
@ -17,7 +17,6 @@ class cloudConnection(object):
|
|||
self.apiKey = apiKey
|
||||
self.securityKey = securityKey
|
||||
self.mgtSvr = mgtSvr
|
||||
self.connection = httplib.HTTPConnection("%s:%d"%(mgtSvr,port), timeout=180)
|
||||
self.port = port
|
||||
self.logging = logging
|
||||
if port == 8096:
|
||||
|
|
@ -25,6 +24,7 @@ class cloudConnection(object):
|
|||
else:
|
||||
self.auth = True
|
||||
|
||||
self.retries = 5
|
||||
self.asyncTimeout = asyncTimeout
|
||||
|
||||
def close(self):
|
||||
|
|
@ -40,27 +40,47 @@ class cloudConnection(object):
|
|||
requests["command"] = command
|
||||
requests["apiKey"] = self.apiKey
|
||||
requests["response"] = "json"
|
||||
requests = zip(requests.keys(), requests.values())
|
||||
requests.sort(key=lambda x: str.lower(x[0]))
|
||||
request = zip(requests.keys(), requests.values())
|
||||
request.sort(key=lambda x: str.lower(x[0]))
|
||||
|
||||
requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests])
|
||||
hashStr = "&".join(["=".join([str.lower(request[0]), str.lower(urllib.quote_plus(str(request[1]))).replace("+", "%20")]) for request in requests])
|
||||
requestUrl = "&".join(["=".join([r[0], urllib.quote_plus(str(r[1]))]) for r in request])
|
||||
hashStr = "&".join(["=".join([str.lower(r[0]), str.lower(urllib.quote_plus(str(r[1]))).replace("+", "%20")]) for r in request])
|
||||
|
||||
sig = urllib.quote_plus(base64.encodestring(hmac.new(self.securityKey, hashStr, hashlib.sha1).digest()).strip())
|
||||
|
||||
requestUrl += "&signature=%s"%sig
|
||||
|
||||
self.connection.request("GET", "/client/api?%s"%requestUrl)
|
||||
try:
|
||||
self.connection = urllib2.urlopen("http://%s:%d/client/api?%s"%(self.mgtSvr, self.port, requestUrl))
|
||||
self.logging.debug("sending request: %s"%requestUrl)
|
||||
response = self.connection.read()
|
||||
self.logging.debug("got response: %s"%response)
|
||||
except IOError, e:
|
||||
if hasattr(e, 'reason'):
|
||||
self.logging.debug("failed to reach %s because of %s"%(self.mgtSvr, e.reason))
|
||||
elif hasattr(e, 'code'):
|
||||
self.logging.debug("server returned %d error code"%e.code)
|
||||
except HTTPException, h:
|
||||
self.logging.debug("encountered http Exception %s"%h.args)
|
||||
if self.retries > 0:
|
||||
self.retries = self.retries - 1
|
||||
self.make_request_with_auth(command, requests)
|
||||
else:
|
||||
self.retries = 5
|
||||
raise h
|
||||
else:
|
||||
return response
|
||||
|
||||
return self.connection.getresponse().read()
|
||||
|
||||
def make_request_without_auth(self, command, requests={}):
|
||||
requests["command"] = command
|
||||
requests["response"] = "json"
|
||||
requests = zip(requests.keys(), requests.values())
|
||||
requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests])
|
||||
self.connection.request("GET", "/&%s"%requestUrl)
|
||||
return self.connection.getresponse().read()
|
||||
|
||||
self.connection = urllib2.urlopen("http://%s:%d/client/api?%s"%(self.mgtSvr, self.port, requestUrl))
|
||||
self.logging.debug("sending request without auth: %s"%requestUrl)
|
||||
response = self.connection.read()
|
||||
self.logging.debug("got response: %s"%response)
|
||||
return response
|
||||
|
||||
def pollAsyncJob(self, jobId, response):
|
||||
cmd = queryAsyncJobResult.queryAsyncJobResultCmd()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ try:
|
|||
except ImportError:
|
||||
import unittest
|
||||
import cloudstackTestClient
|
||||
|
||||
class cloudstackTestCase(unittest.case.TestCase):
|
||||
def __init__(self, args):
|
||||
unittest.case.TestCase.__init__(self, args)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import logging
|
|||
from cloudstackAPI import *
|
||||
from optparse import OptionParser
|
||||
|
||||
module_logger = "testclient.deploy"
|
||||
|
||||
|
||||
class deployDataCenters():
|
||||
|
||||
|
|
@ -266,7 +268,8 @@ class deployDataCenters():
|
|||
zoneId)
|
||||
|
||||
self.createSecondaryStorages(zone.secondaryStorages, zoneId)
|
||||
return self.enableZone(zoneId, "Enabled")
|
||||
self.enableZone(zoneId, "Enabled")
|
||||
return
|
||||
|
||||
def registerApiKey(self):
|
||||
listuser = listUsers.listUsersCmd()
|
||||
|
|
@ -294,7 +297,7 @@ class deployDataCenters():
|
|||
self.config = configGenerator.get_setup_config(self.configFile)
|
||||
except:
|
||||
raise cloudstackException.InvalidParameterException( \
|
||||
"Failed to load cofig" + sys.exc_info())
|
||||
"Failed to load config" + sys.exc_info())
|
||||
|
||||
mgt = self.config.mgtSvr[0]
|
||||
|
||||
|
|
@ -313,8 +316,9 @@ class deployDataCenters():
|
|||
|
||||
testClientLogger = None
|
||||
if testClientLogFile is not None:
|
||||
testClientLogger = logging.getLogger("testClient")
|
||||
testClientLogger = logging.getLogger("testclient.deploy.deployDataCenters")
|
||||
fh = logging.FileHandler(testClientLogFile)
|
||||
fh.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s"))
|
||||
testClientLogger.addHandler(fh)
|
||||
testClientLogger.setLevel(logging.DEBUG)
|
||||
self.testClientLogger = testClientLogger
|
||||
|
|
|
|||
|
|
@ -48,7 +48,16 @@
|
|||
cache: false,
|
||||
error: function(data) {
|
||||
cloudStack.dialog.notice({ message: parseXMLHttpResponse(data) });
|
||||
}
|
||||
},
|
||||
beforeSend: function(XMLHttpRequest) {
|
||||
if (g_mySession == $.cookie("JSESSIONID")) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
cloudStack.dialog.notice({ message: _l('label.session.expired') });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var $container = $('#cloudStack3-container');
|
||||
|
|
@ -57,56 +66,66 @@
|
|||
$container: $container,
|
||||
|
||||
// Use this for checking the session, to bypass login screen
|
||||
bypassLoginCheck: function(args) {
|
||||
g_mySession = $.cookie("JSESSIONID");
|
||||
g_sessionKey = $.cookie("sessionKey");
|
||||
g_role = $.cookie("role");
|
||||
g_type = $.cookie("type");
|
||||
g_username = $.cookie("username");
|
||||
g_account = $.cookie("account");
|
||||
g_domainid = $.cookie("domainid");
|
||||
g_timezone = $.cookie("timezone");
|
||||
g_userPublicTemplateEnabled = $.cookie("userpublictemplateenabled");
|
||||
g_userfullname = $.cookie('userfullname');
|
||||
g_userid = $.cookie('userid');
|
||||
|
||||
if($.cookie("timezoneoffset") != null)
|
||||
g_timezoneoffset = isNaN($.cookie("timezoneoffset"))?null: parseFloat($.cookie("timezoneoffset"));
|
||||
else
|
||||
g_timezoneoffset = null;
|
||||
|
||||
if (g_userPublicTemplateEnabled == null || g_userPublicTemplateEnabled.length == 0)
|
||||
g_userPublicTemplateEnabled = "true";
|
||||
|
||||
if(g_supportELB == null)
|
||||
g_supportELB = $.cookie("supportELB");
|
||||
|
||||
bypassLoginCheck: function(args) { //before login screen
|
||||
if (g_loginResponse == null) { //not single-sign-on
|
||||
g_mySession = $.cookie('JSESSIONID');
|
||||
g_sessionKey = $.cookie('sessionKey');
|
||||
g_role = $.cookie('role');
|
||||
g_username = $.cookie('username');
|
||||
g_userid = $.cookie('userid');
|
||||
g_account = $.cookie('account');
|
||||
g_domainid = $.cookie('domainid');
|
||||
g_userfullname = $.cookie('userfullname');
|
||||
g_timezone = $.cookie('timezone');
|
||||
if($.cookie('timezoneoffset') != null)
|
||||
g_timezoneoffset = isNaN($.cookie('timezoneoffset'))? null: parseFloat($.cookie('timezoneoffset'));
|
||||
else
|
||||
g_timezoneoffset = null;
|
||||
}
|
||||
else { //single-sign-on
|
||||
g_mySession = $.cookie('JSESSIONID');
|
||||
g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
|
||||
g_role = g_loginResponse.type;
|
||||
g_username = g_loginResponse.username;
|
||||
g_userid = g_loginResponse.userid;
|
||||
g_account = g_loginResponse.account;
|
||||
g_domainid = g_loginResponse.domainid;
|
||||
g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
|
||||
g_timezone = g_loginResponse.timezone;
|
||||
if(g_loginResponse.timezoneoffset != null)
|
||||
g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset)? null: parseFloat(g_loginResponse.timezoneoffset);
|
||||
else
|
||||
g_timezoneoffset = null;
|
||||
}
|
||||
|
||||
var userValid = false;
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listCapabilities"),
|
||||
dataType: "json",
|
||||
async: false,
|
||||
success: function(json) {
|
||||
g_capabilities = json.listcapabilitiesresponse.capability;
|
||||
$.cookie('capabilities', g_capabilities, { expires: 1});
|
||||
|
||||
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
||||
$.cookie('supportELB', g_supportELB, { expires: 1});
|
||||
|
||||
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
||||
$.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
|
||||
|
||||
|
||||
if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
|
||||
g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
|
||||
$.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, { expires: 1});
|
||||
}
|
||||
|
||||
g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
|
||||
$.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
|
||||
|
||||
userValid = true;
|
||||
},
|
||||
error: function(xmlHTTP) {
|
||||
logout(false);
|
||||
},
|
||||
beforeSend: function(xmlHTTP) {
|
||||
return true;
|
||||
}
|
||||
beforeSend : function(XMLHttpResponse) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (userValid && isAdmin()) {
|
||||
|
|
@ -130,8 +149,7 @@
|
|||
username: g_username,
|
||||
account: g_account,
|
||||
name: g_userfullname,
|
||||
role: g_role,
|
||||
type: g_type,
|
||||
role: g_role,
|
||||
domainid: g_domainid
|
||||
}
|
||||
} : false;
|
||||
|
|
@ -173,8 +191,7 @@
|
|||
|
||||
g_mySession = $.cookie('JSESSIONID');
|
||||
g_sessionKey = encodeURIComponent(loginresponse.sessionkey);
|
||||
g_role = loginresponse.type;
|
||||
g_type = loginresponse.type;
|
||||
g_role = loginresponse.type;
|
||||
g_username = loginresponse.username;
|
||||
g_userid = loginresponse.userid;
|
||||
g_account = loginresponse.account;
|
||||
|
|
@ -187,20 +204,20 @@
|
|||
$.cookie('username', g_username, { expires: 1});
|
||||
$.cookie('account', g_account, { expires: 1});
|
||||
$.cookie('domainid', g_domainid, { expires: 1});
|
||||
$.cookie('role', g_role, { expires: 1});
|
||||
$.cookie('type', g_type, { expires: 1});
|
||||
$.cookie('role', g_role, { expires: 1});
|
||||
$.cookie('timezoneoffset', g_timezoneoffset, { expires: 1});
|
||||
$.cookie('timezone', g_timezone, { expires: 1});
|
||||
$.cookie('userfullname', g_userfullname, { expires: 1 });
|
||||
$.cookie('userid', g_userid, { expires: 1 });
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listCapabilities"),
|
||||
//url: "command=/client/api?listCapabilities&sessionkey="+g_sessionKey,
|
||||
url: createURL("listCapabilities"),
|
||||
dataType: "json",
|
||||
async: false,
|
||||
success: function(json) {
|
||||
g_capabilities = json.listcapabilitiesresponse.capability;
|
||||
$.cookie('capabilities', g_capabilities, { expires: 1});
|
||||
|
||||
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
|
||||
$.cookie('supportELB', g_supportELB, { expires: 1});
|
||||
|
||||
|
|
@ -224,7 +241,7 @@
|
|||
},
|
||||
error: function(xmlHTTP) {
|
||||
args.response.error();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (isAdmin()) {
|
||||
|
|
@ -248,7 +265,10 @@
|
|||
},
|
||||
error: function() {
|
||||
args.response.error();
|
||||
}
|
||||
},
|
||||
beforeSend : function(XMLHttpResponse) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -281,9 +301,11 @@
|
|||
},
|
||||
error: function() {
|
||||
document.location.reload();
|
||||
}
|
||||
},
|
||||
beforeSend : function(XMLHttpResponse) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// Show cloudStack main UI widget
|
||||
|
|
@ -340,7 +362,10 @@
|
|||
},
|
||||
error: function() {
|
||||
cloudStack.uiCustom.login(loginArgs);
|
||||
}
|
||||
},
|
||||
beforeSend : function(XMLHttpResponse) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Localization
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
accountID: user.userid,
|
||||
accountName: user.account,
|
||||
userName: user.username,
|
||||
accountType: cloudStack.converters.toRole(user.type),
|
||||
accountType: user.role,
|
||||
accountDomainID: user.domainid
|
||||
}));
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue